Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 作为非typename模板参数传递超类函数_C++_Templates - Fatal编程技术网

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)()