为什么对模板化基类的函数调用不起作用?

时间:2010-02-19 21:00:21

标签: 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:
        void g() {
            cout << "B::g()\n";
            A<T>::f();
        }
};

int main() {
    B<int> b;     // (1)
    b.g();        // (2)

    return 0;
}

显然,对于int模板类型,对B :: g()内部的A :: f()的调用将失败。我的问题是呼叫在什么时候失败了?在(1)或(2)?我认为它应该是(1)因为在那时编译器创建一个模板类型为int的新类并编译它。那个编译应该在f()中失败吗?

2 个答案:

答案 0 :(得分:4)

它将在(2)失败,这由标准保证。在第14.7.1 / 1节中,它说实例化模板类实例化它的成员定义。只有在使用该成员后才会发生这种情况。

如果从代码中删除(2),它将编译。

  14.7.1 / 1摘录:
  类模板特化的隐式实例化会导致隐式   实例化类成员函数,成员类,静态数据成员和成员模板的声明,但不是定义或默认参数;它会导致成员匿名联合的定义的隐式实例化。

强调我的。


Visual Studio的诊断具有误导性。它会说see reference to class template instantiation 'B<T>' being compiled。它的含义不是“我在B<T>的实例化失败”,而是“我没有实例化类B<T>的成员”

答案 1 :(得分:3)

2)失败。模板的成员函数在被调用时被实例化。

更准确地说:当实例化类模板时,实例化其成员函数的声明,但不是它们的定义。使用该函数时,将实例化该定义。