这段代码有什么问题?由于这个答案,我以为我可以转换:
Is it safe to "upcast" a method pointer and use it with base class pointer?
struct B
{
void f(){}
};
struct D : B
{
virtual ~D(){}
};
template <typename FP, FP fp>
void g()
{
}
int main()
{
g<void (D::*)(), &B::f>();
return 0;
}
错误:
t.cpp:18:27: error: could not convert template argument '&B::f' to 'void (D::*)()'
g<void (D::*)(), &B::f>();
这也不起作用:
g<void (D::*)(), static_cast<void (D::*)()>(&B::f)>();
答案 0 :(得分:4)
标准不允许这样做(C ++ 11,[temp.arg.nontype]§5):
对用作非类型模板参数的每个表达式执行以下转换。如果非类型 template-argument 无法转换为类型相应的模板参数然后程序格式不正确。
...
- 对于指向成员函数的类型指针的非类型 template-parameter ,如果 template-argument 的类型为
std::nullptr_t
,则为null成员指针转换(4.11)适用; 否则,不适用转化。如果template-argument表示一组重载的成员函数,则从集合中选择匹配的成员函数(13.4)。
(强调我的)
由于[temp.arg.nontype]§1:,也不允许强制转换
非类型非模板模板参数的 template-argument 应为以下之一:
...
- 指向成员的指针,如5.3.1所述。
5.3.1§4的内容为:
只有在使用显式
&
并且其操作数是 qualified-id 未括在括号中时,才会形成指向成员的指针。
这结合起来说不允许使用强制转换作为非类型模板参数。
因此,尽管在运行时可以进行此类转换,但似乎无法将它们用作模板参数。