当基类和派生都使用派生类型参数

时间:2017-04-30 23:06:37

标签: c++ c++11 templates inheritance

我很难理解为什么以下代码无法编译:

template <class T>
class Base {
    public:
        Base(int a){}
};
template <class T>
class Derived: public Base<T>  {
    public:
        Derived(int a): Base(a){}
};
int main(){}

在我的编译器(gcc 5.4.0 with C ++ 11)上输出错误消息

error: class 'Derived<T>' does not have any field named 'Base'
         Derived(int a): Base(a){}

我发现这有点类似于Template base constructor call in member initialization list error,尽管这个测试用例实际上是为我编译的,而这个测试用例却没有:主要区别似乎是BaseDerived使用相同的类型参数。此外,如果我明确添加类型参数或者为base提供明确的范围,它编译得很好,如

template <class T>
class Base {
    public:
        Base(int a){}
};

template <class T>
class Derived: public Base<T>  {
    public:
        Derived(int a): Derived::Base(a){}
};

int main(){}

发生了什么事?在注入类名时我是否会误解?

1 个答案:

答案 0 :(得分:5)

注入的类名Base是类Base的成员,并且由于基类是相关的,因此在非限定名称查找期间不会搜索其范围。因此,使用名称Base将只找到类模板,而不是Base<T>的注入类名。这就是你必须写Base<T>

的原因

Derived::Base有效,因为它会导致名称查找被推迟,直到Derived被实例化。