纯虚函数的模板专业化

Nuj*_*fas 3 c++ templates virtual-functions

如何专门化在基类中定义为纯函数的模板化函数?

struct A {
    virtual void func(int a) = 0;
    //virtual void func(int a) {} // replace above line with this and it works
};

struct B : public A {
    template<typename T> void func(T t) {
        cout <<"hello"<<endl;
    }
};
template<> void B::func<int>(int a) { cout <<"hello 2"<<endl; }


int main() {
    B b;
    b.func(2);
}
Run Code Online (Sandbox Code Playgroud)

错误:

错误:变量类型“ B”是抽象类B b;^注意:'B'中的未实现的纯虚拟方法'func'虚拟void func(int a)= 0;

son*_*yao 5

虚拟功能只能由非模板功能覆盖。在这种情况下,

然后,Derived类中的该函数也是虚拟的(在其声明中是否使用了关键字virtual),并覆盖了Base :: vf(在其声明中是否使用了override这个词)。

并且请注意函数模板不能是虚拟函数 ;

功能模板不能声明为虚拟的。

根据标准,[temp.mem] / 4

成员函数模板的特殊化不会覆盖基类中的虚函数。[?例:

class B {
  virtual void f(int);
};

class D : public B {
  template <class T> void f(T); // does not override B?::?f(int)
  void f(int i) { f<>(i); }     // overriding function that calls the template instantiation
};
Run Code Online (Sandbox Code Playgroud)

-?示例?]

关于你的问题

如果将函数设为“非纯函数”,为什么会起作用?

出现编译错误,但仍无法按您预期的那样工作。派生类中的函数模板不会覆盖基类的虚函数。您可以使用动态调度进行检查:

如果使用指针或对基类的引用来处理派生类,则对重写的虚函数的调用将调用派生类中定义的行为。

请注意,您应该使用指针或引用来进行动态调度,例如

B b;
A* pa = &b;
pa->func(2);
Run Code Online (Sandbox Code Playgroud)

生活

您还可以应用覆盖说明符来帮助您确认覆盖

  • 您只能使用虚函数进行覆盖。覆盖是隐式虚拟的。尝试将功能标记为“覆盖” (2认同)
  • @StackDanny Pertty确信他们说的是将其标记为“ override”,这样他们会得到编译器错误,指出无法使用模板。 (2认同)