C++ 为什么编译器允许在模板类中使用此虚拟函数?

C++ 为什么编译器允许在模板类中使用此虚拟函数?,c++,C++,我知道关于这个话题没有什么线索。但真正让我困惑的是,我得到的结果与大家所说的不一样 查看下面的代码(使用GCC441编译): 若模板类中不允许使用虚函数,为什么会得到这个结果 类中不能有虚拟函数模板,但类模板中可以有虚拟函数 一旦该类模板Foo被实例化,生成的类Foo就具有虚拟函数,可以像使用任何其他类型的函数一样使用这些函数 让我们来看看两者之间的区别: 不好 structfoo{ 模板 virtual void bar(){}//Foo::bar-禁止,标记为“virtual” }; //无

我知道关于这个话题没有什么线索。但真正让我困惑的是,我得到的结果与大家所说的不一样

查看下面的代码(使用GCC441编译):

若模板类中不允许使用虚函数,为什么会得到这个结果

类中不能有虚拟函数模板,但类模板中可以有虚拟函数

一旦该类模板
Foo
被实例化,生成的类
Foo
就具有虚拟函数,可以像使用任何其他类型的函数一样使用这些函数

让我们来看看两者之间的区别:

不好
structfoo{
模板
virtual void bar(){}//Foo::bar-禁止,标记为“virtual”
};
//无法在运行时解析对Foo::bar()的调用,因为
//此类调用可能需要模板实例化,这可能只会发生
//在编译时。
好啊
模板
结构Foo{
虚拟void bar(){}//Foo::bar
};
//如果程序中使用了Foo,那么它将整体存在。
//因此,Foo::bar()可以用作noraml。
行为是正确的。
您提到的就是虚拟成员函数模板。

我猜模板虚拟函数和虚拟函数模板类之间有区别。我说的对吗?你读过这个吗@Orunner:Vandevoorde/Josuttis还建议将“模板”放在它所指的后面:“类模板”->
模板类X,“函数模板”->
模板void foo(),“成员函数模板”->
类X{templatevoid foo();},“类模板成员函数模板”->
模板类X{template void foo();};这样可以保持一致性和明确性。@phresnel:严格来说,这是因为“类”不是“模板”所指的;相反,在“类模板”中,“模板”指的是“类”。“Template”是名词,“class”是形容词名词,用于描述模板的类型:红色模板、cookie模板、函数模板。根据我的经验,以这种方式思考也有助于语言新手更容易地掌握模板实例化的各种概念,而不是像“普通函数”的兄弟变体那样思考“模板函数”。
#include <iostream>

using namespace std;

template<class T>
class A {
  public:
    A(T &t) : _a(t) {};
    virtual ~A() { cout << "Dtor-A" << endl;};
    virtual void print () { cout << "A: " << _a << endl; }
    T _a;
};

class B : public A<int> {
  public:
    B(int t) : A<int>(t) {}
    ~B() { cout << "Dtor-B" << endl;};
    void print() { cout << "B: " << endl; }
};

int main() {
  B b(2);

  A<int> *a = &b;
  a->print();

  A<int> *a2 = new B(4);
  a2->print();

  delete a2;
}
B: 
B: 
Dtor-B
Dtor-A
Dtor-B
Dtor-A
struct Foo {
   template <typename T>
   virtual void bar() {}      // Foo::bar<T> - prohibited, as marked "virtual"
};

// Impossible to resolve calls to Foo::bar<T>() at runtime, since
// such calls may require template instantiation, which may only occur
// at compile-time.
template <typename T>
struct Foo {
   virtual void bar() {}      // Foo<T>::bar
};

// If Foo<T> is used in the program, then it will exist, in entirety.
// Foo<T>::bar() may thus be used as noraml.