不能将重载函数指针转换为成员函数指针
Cannot convert overloaded function pointer to member function pointer?
我的代码如下
class A
{
public:
int Key() const;
};
class B : public A
{};
template<class T, int (T::*MemFunction)() const>
class TT
{
public:
int Get() const {return (m_t.*MemFunction)();}
private:
T m_t;
};
TT<B, &B::Key> t; // Wrong, cannot convert overloaded function
// to int (T::*MemFunction)() (VS2010)
相似的方式为什么和如何工作?由于
billz已经给出了答案,但我会尽量给出一个解释。
在c++中,当获取指向成员的指针时,表达式的结果不是指向该表达式中存在的类型的成员的指针,而是指向成员所在类型的成员的指针。即表达式&B::Key
得到&A::Key
,因为成员函数Key
在A
中定义,而不在B
中定义。这是在§5.3.1/3中定义的,它很难阅读,但附带了一个例子:
一元&Operator是指向其操作数的指针。操作数应为左值或限定id。如果操作数是一个限定id,命名某个类型为T的类C的非静态成员m,则结果的类型为"指向类型为T的类C成员的指针",并且是一个指定C::m的右值。否则,如果表达式的类型为T,则结果具有"指向T的指针"类型,并且是一个右值,该右值是指定对象的地址(1.7)或指向指定函数的指针。[注:特别地,类型为"cv T"的对象的地址是"指向cv T的指针",具有相同的cv-限定符。- end note][示例:
]
struct A { int i; };
struct B : A { };
... &B::i ... // has type int A::*
- end示例]
这意味着你的模板实例化相当于:
TT<B, &A::Key>
虽然指向基类成员的成员指针可以转换为指向派生类型的成员指针,但对于非类型非模板模板形参的特殊情况,不允许转换。非类型非模板模板形参的转换在§14.3.2/5中定义,对于这种特殊情况,它规定:
对于指向成员函数的指针类型的非类型模板形参,如果模板形参的类型为std::nullptr_t,则应用空成员指针转换(4.11);否则,不应用任何转换。
由于&A::Key
不能收敛到int (B::*)() const
,模板实例化是病态的。通过在模板实例化中添加强制转换,您可以强制转换在模板实例化之前发生,并且实例化变得有效,因为不需要转换。
转换应该使它工作:
typedef int (B::*Key)() const;
TT<Key(&B::Key)> t;
t.Get();
- 如何正确编写指针函数声明?
- C++常规指针函数或模板
- 如何重新定义 C++ 指针函数?
- C++ 指向其他类函数的指针函数
- 指针到指针函数参数
- 将指向成员的指针函数传递到模板中
- C++ 在 none 常量指针函数中返回一个常量指针
- 如何使用指针函数编写/读取数组
- 是C 中的函数指针函数对象
- 如何从另一个类调用指向成员的指针函数
- 如何声明采用指向成员的指针函数的函数
- 如何构造一个以可变参数指针函数作为成员的类?
- c 通过值或指针函数语法
- 将typedef方法作为指针函数传递
- 从 Main 中的双指针函数打印出指针数组
- strcpy 对指针函数的引用
- 这是否仍然声明一种指针函数的别名?
- 将指向成员的指针函数与 std::shared_ptr 结合使用
- 'Incomplete type' 为标准::函数声明指向成员的指针函数模板参数时出错
- 从注入进程的 DLL 调用函数并更改指针函数的地址