C++ 作为非typename模板参数传递超类函数
假设你有C++ 作为非typename模板参数传递超类函数,c++,templates,C++,Templates,假设你有 struct A{ void f(){} }; struct B:public A{ }; template<typename C,void (C::*f)()> struct Call{ void operator()(C* c){ (c->*f)(); } }; 工作但是 Call<B,&B::f> a; ? (呼叫显然有效) 以类似的方式 const void (B::*f)()=&B::f;
struct A{
void f(){}
};
struct B:public A{
};
template<typename C,void (C::*f)()>
struct Call{
void operator()(C* c){
(c->*f)();
}
};
工作但是
Call<B,&B::f> a;
?
(呼叫
显然有效)
以类似的方式
const void (B::*f)()=&B::f;
给予
该错误准确地说明了错误所在,
void(A::*)()
和void(B::*)()
是不同的类型
在这种情况下,似乎应该很容易做到,但一般情况变得更加复杂。考虑一下如果<代码> <代码>有几个虚拟函数,而<>代码> b/COD>具有多重继承,将会发生什么。指向成员函数的指针非常复杂,因为它们必须考虑这类事情。看看
您可以将B
更改为:
struct B:public A{
void f() { A::f(); }
};
所以B::f()
实际上是存在的。现在B::f()
是A::f()
的别名,它显然属于void(A::*)()
类型,而不是void(B:*)()
因为隐式转换来自
void (A::*f)()
到
应用
4.11(2)
“指向cv T类型B的成员的指针”类型的prvalue(其中B是类类型)可以转换为A
“指向cv T类型D成员的指针”类型的prvalue,其中D是B的派生类(第10条)。
但是,标准不允许在模板参数中对指向成员函数的指针进行任何转换,nullptr\t转换除外:
14.3.2
对于指向成员函数指针类型的非类型模板参数,如果模板参数为
类型std::nullptr_t,应用空成员指针转换(4.11);否则,没有转换
申请。如果模板参数表示一组重载成员函数,则匹配的成员
从集合(13.4)中选择功能。
我完全同意你的观点。我想知道为什么会有void(B::*f)(=&B::f;那么。顺便说一句,const void(B::*f)(=&B::f;不被接受为well@FabioDallaLibera有不同的规则:模板参数必须是相同的类型,而赋值运算符可以使用可转换的类型。你不会期望
std::vector a;std::载体b;a=b
可以工作,因为char
可以隐式转换为int
。太好了,谢谢!顺便问一下,你也知道constvoid(B::*f)(=&B::f;也不被接受?@Fabio:void(B::*const f)(=&B::f工作正常:)。constvoid(B::*f)()表示指向返回constvoid值的方法的指针,因此在后一种情况下,方法的签名不匹配。
cannot convert ‘void (A::*)()’ to ‘const void (B::*)()’ in initialization
struct B:public A{
void f() { A::f(); }
};
void (B::*f)()=&B::f;
void (A::*f)()
void (B::*f)()