c++ - 获取模板基类的类型

标签 c++ templates inheritance

下一段代码工作正常(这是我的其他问题的过度简化版本,类型更长、更深、模板更多):

template<class C>
struct Base
{};

template<class C>
struct Derived : public Base<C>
{
   Derived() : Base<C>()
   {}
};

但是,如果不“写入”基类的完整类型,我怎么能调用基类构造函数呢?例如,我试过类似的东西:

template<class C>
struct Base
{
   typedef Base base_type;
};

template<class C>
struct Derived : public Base<C>
{
   Derived() : base_type() {}
};

int main()
{
   Derived<void> b;
}

但无法识别“base_type”。 gcc 抛出的消息是:

test3.cpp: In constructor 'Derived<C>::Derived()':
  test3.cpp:100:17: error: class 'Derived<C>' does not have any field
  named 'base_type'

要解决它,我必须写 Base<C>::base_type在构造函数中,但这将使 base_type 存在本身无关紧要。

难道我的写作 Thrift 运动不可能吗?

还有,为什么 base_type在构造函数中找不到,但是这工作正常吗?

int main()
{
   Derived<void>::base_type b;
}

编辑: 加上 @Jack Aidley 的评论我发现使用简单别名获取基类类型的最佳形式是:

template<typename C> struct Base {};

template<typename C, typename Base>
struct Derived_impl : public Base
{
    Derived_impl() : Base()
    {}
};

template<typename C>
using Derived = Derived_impl<C, Base<C> >;

int main()
{
   Derived<void> b;
}

最佳答案

按照标准

When looking for the declaration of a name used in a template definition, the usual lookup rules (3.4.1, 3.4.2) are used for nondependent names. The lookup of names dependent on the template parameters is postponed until the actual template argument is known (14.6.2).

这意味着,你必须告诉编译器,Base 类中的 base_type 依赖于 C。例如,您可以使用:

template<class C>
struct Derived : public Base<C>
{
    using typename Base<C>::base_type;

    Derived() : base_type() {}
};

或者这个

template<class C>
struct Derived : public Base<C>
{
    Derived() : Derived<C>::base_type() {} 

    // or, as you already told, Base<C>::base_type()
};

关于c++ - 获取模板基类的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14749461/

相关文章:

从实现 IComparable<T> 的东西继承时,C# BinarySearch 中断了吗?

c++ - 为什么我会收到以下错误 : In constructor 'B::B(int, int)' : no matching function for call to 'A::A()'

c++ - 什么是 Linux 上易于使用的 C++ 分析器?

c++ - 在 COM 中调用 QueryInterface() 是绝对必要的吗?

c++ - 匿名命名空间中类的 ADL

c++ - 是否需要为每个模板函数声明模板<typename T>?

C++虚拟继承初始化列表

c++ - 在 C++ 中扩展数组

c# - 在 C++ 和 C# 之间编码类实例的指针

c++ - 在 C++ 中绑定(bind) lambda