【问题标题】:Compiler Error When Calling Base Constructor when both Base and Derived are Templated With Derived Type Parameter使用派生类型参数对基类和派生类进行模板化时调用基类构造函数时的编译器错误
【发布时间】:2017-09-28 11:09:45
【问题描述】:

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

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(){}

在我的编译器(带有 C++ 11 的 gcc 5.4.0)上,这会输出错误消息

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(){}

发生了什么事?什么时候可以使用注入的类名是我误解了吗?

【问题讨论】:

  • 为什么不派生:Base (a)?
  • 请注意it works as is with MSVC,因为 MSVC 的名称查找与 GCC 不同。尽管措辞不同,但 Clang 会发出与 GCC 相同的错误。

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


【解决方案1】:

注入的类名Base是类Base的成员,由于基类是依赖的,所以在非限定名查找时不会搜索其范围。因此,使用名称Base 只会找到类模板,而不是Base&lt;T&gt; 的注入类名称。这就是为什么你必须写Base&lt;T&gt;

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

【讨论】:

    猜你喜欢
    • 2016-07-19
    • 2017-06-12
    • 2011-06-04
    • 1970-01-01
    • 1970-01-01
    • 2021-04-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多