在尝试调用接受类型和该类型的参数/参数作为模板参数/参数的函数模板时,编译器会给出类似参数/参数不会产生的错误。所以我想知道在调用 vector 类的成员函数“operator[]const”的函数模板时正确的参数/参数是什么!
考虑这段代码:
class test_class{
public:
int member;
int& operator[](size_t) {return member;}
const int& operator[](size_t) const{return member;}
};
typedef std::vector<int> vector_type;
typedef const int&(test_class::* OK_type)(size_t)const;
typedef const int&(vector_type::* not_OK_type)(size_t)const;
static constexpr OK_type OK_pointer = &test_class::operator[];
static constexpr not_OK_type not_OK_pointer = &vector_type::operator[];
template<typename t__, t__>
void function(){}
上面的代码没问题了,现在考虑main函数:
int main() {
function<OK_type, OK_pointer>();
function<not_OK_type, not_OK_pointer>();
return 0;
}
第一次调用函数模板可以,但第二次就不行了。 编译器产生的错误是:
error: no matching function for call to ‘function<not_OK_type, not_OK_pointer>()’
note: candidate: ‘template<class t__, t__ <anonymous> > void function()’
note: template argument deduction/substitution failed:
error: ‘const int& (std::vector<int>::*)(size_t) const{((const int& (std::vector<int>::*)(size_t) const)std::vector<int>::operator[]), 0}’ is not a valid template argument for type ‘const int& (std::vector<int>::*)(long unsigned int) const’
function<not_OK_type, not_OK_pointer>();
note: it must be a pointer-to-member of the form ‘&X::Y’
有趣的是,即使函数模板的形式如下:
template<auto>
void function(){}
它会导致相同的结果。
我必须补充一点,在非 const 版本的情况下,错误是相同的(对于 std::vector
)。
所以我想知道
答:怎么了?
B:考虑到如果 not_OK_type
和 &vector_type::operator[]
之间存在不匹配,那么编译器也会在以下情况下给出错误:
static constexpr not_OK_type not_OK_pointer = &vector_type::operator[];
可用作 constexpr 的类型与可用作模板参数/参数的类型之间有区别吗?
最佳答案
问题是typedef const int&(vector_type::* not_OK_type)(size_t)const;
。
如果您看到 STL_vector.h
( here ),则运算符[] 在第 1040 行被声明为 noexcept
。
但是在not_OK_type
变量的声明中,noexcept
不存在。这就是编译器提示的原因。
要消除编译错误,请将 noexcept
添加到 not_OK_type
变量中。像这样:
typedef const int&(vector_type::* not_OK_type)(size_t)const noexcept;
工作代码:
#include <vector>
class test_class{
public:
int member;
int& operator[](size_t) {return member;}
const int& operator[](size_t) const{return member;}
};
typedef std::vector<int> vector_type;
typedef const int&(test_class::* OK_type)(size_t)const;
typedef const int&(vector_type::* not_OK_type)(size_t)const noexcept;
static constexpr OK_type OK_pointer = &test_class::operator[];
static constexpr not_OK_type not_OK_pointer = &vector_type::operator[];
template<typename t__, t__>
void function(){}
int main() {
function<OK_type, OK_pointer>();
function<not_OK_type, not_OK_pointer>();
return 0;
}
关于c++ - 作为成员函数的operator[] 的正确模板参数/参数是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56070755/