C++ 为什么对模板化基类的函数调用不起作用?
考虑以下示例:C++ 为什么对模板化基类的函数调用不起作用?,c++,templates,C++,Templates,考虑以下示例: template <typename T> class A { public: void f() { cout << "A::f()\n"; } }; template<> class A<int> { }; template<typename T> class B: public A<T> { public: voi
template <typename T>
class A {
public:
void f() {
cout << "A::f()\n";
}
};
template<>
class A<int> {
};
template<typename T>
class B: public A<T> {
public:
void g() {
cout << "B::g()\n";
A<T>::f();
}
};
int main() {
B<int> b; // (1)
b.g(); // (2)
return 0;
}
模板
甲级{
公众:
void f(){
cout在2)失败。模板的成员函数在调用时实例化
更准确地说:实例化类模板时,实例化其成员函数的声明,但不实例化其定义。在使用函数时实例化定义。它将在(2)处失败,这是由标准保证的。在第14.7.1/1节中,它说实例化模板类不会实例化它的成员定义。这只会在使用成员后发生
如果从代码中删除(2),它将编译
14.7.1/1摘录:
类模板专门化的隐式实例化会导致隐式
类成员函数、成员类、静态数据成员和成员模板的声明的实例化,而不是定义或默认参数的实例化,;它会导致成员匿名联合定义的隐式实例化
我的
Visual Studio的诊断具有误导性。它会说请参见正在编译的类模板实例化“B”的引用
。它的意思不是“我在实例化B
时失败了”,而是“我在实例化类B
的成员时失败了”@John:没有,因为编译会失败。哦,好吧。我很困惑,因为你说的是“调用在什么时候失败,”--并在代码中注释了点--就好像它已经编译过一样。最好的是VC只指向实例化B
的行。无论如何,我现在应该学会怀疑VC,只需首先查找它。一个有趣的事实是,如果从所有模板定义或函数的显式专门化中删除函数f
A
在该TU中,编译器可以标记成员函数g
的定义格式不正确,即使从未使用B
,也可以发出诊断,因为无法为该成员函数生成有效的专门化(14.7/8
)。