当Base和Derived都使用派生类型参数进行模板化时调用基础构造函数时出现编译器错误

use*_*012 4 c++ inheritance templates c++11

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

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(){}
Run Code Online (Sandbox Code Playgroud)

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

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

我看到这有点类似于成员初始化列表错误中的模板基础构造函数调用,尽管该测试用例实际上为我编译而这个不是:主要区别似乎是两者Base并Derived使用相同的类型参数.另外,如果我明确添加类型参数或者为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(){}
Run Code Online (Sandbox Code Playgroud)

这是怎么回事?在注入类名时我是否会误解?

Bri*_*ian 5

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

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