c++ - 作为成员函数的operator[] 的正确模板参数/参数是什么?

标签 c++ templates parameters arguments

在尝试调用接受类型和该类型的参数/参数作为模板参数/参数的函数模板时,编译器会给出类似参数/参数不会产生的错误。所以我想知道在调用 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/

相关文章:

c++ - 使用数据类型模板的函数不应该返回 long long int 吗?

c++ - 多态基类指针

symfony - 如何将 Twig 表达式作为参数传递给模板,然后使用模板的上下文执行它?

php - 如何使用 Apache Mod_rewrite 删除 php 扩展,同时保留 GET 参数?

c++ - 通过 libcouchbase-cxx 发出准备好的/参数化的查询

c++ - boost:初始化共享指针重置与 make_shared

c++ - vector 循环未到达所有元素

c++ - 模板推导中的const T&和T&有什么区别

c - const char *src 中的星号是什么意思?

python - 参数化生成器?