假设你有
struct A{
void f(){}
};
struct B:public A{
};
template<typename C,void (C::*f)()>
struct Call{
void operator()(C* c){
(c->*f)();
}
};
Run Code Online (Sandbox Code Playgroud)
为什么
int main(){
void (B::*f)()=&B::f;
}
Run Code Online (Sandbox Code Playgroud)
工作但是
Call<B,&B::f> a;
Run Code Online (Sandbox Code Playgroud)
没有,抱怨
could not convert template argument ‘&A::f’ to ‘void (B::*)()
Run Code Online (Sandbox Code Playgroud)
?
(Call<A,&A::f>显然有效)
以类似的方式
const void (B::*f)()=&B::f;
Run Code Online (Sandbox Code Playgroud)
给
cannot convert ‘void (A::*)()’ to ‘const void (B::*)()’ in initialization
Run Code Online (Sandbox Code Playgroud)
void (B::*f)()=&B::f; \nRun Code Online (Sandbox Code Playgroud)\n\n之所以有效,是因为隐式转换来自
\n\nvoid (A::*f)() \nRun Code Online (Sandbox Code Playgroud)\n\n到
\n\nvoid (B::*f)()\nRun Code Online (Sandbox Code Playgroud)\n\n被申请;被应用。
\n\n\n4.11 (2)
\n\n\xe2\x80\x9c 类型的纯右值,指向 cv T\xe2\x80\x9d 类型的 B 成员,其中 B 是类类型,可以转换为 \n\n\xe2\x80\x9c 类型的纯右值,指向 cv T\xe2\x80\x9d 类型的成员D 类型为 cv T\xe2\x80\x9d,其中 D 是 B 的派生类(第 10 条)。\n
\n\n但是,该标准不允许对模板参数中的成员函数指针进行任何转换,除了 nullptr_t 转换:
\n\n\n14.3.2
\n\n对于指向成员函数的指针类型的非类型模板参数,如果模板参数的类型为 std::nullptr_t,则应用空成员指针转换 (4.11);否则,不进行任何转换\n。如果模板参数表示一组重载成员函数,则从该组\n中选择匹配的成员函数(13.4)。\n
\n| 归档时间: |
|
| 查看次数: |
250 次 |
| 最近记录: |