1

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

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自身的存在变得无关紧要。

难道是我的省写运动不可能吗?

而且,为什么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;
}
4

2 回答 2

2

根据标准

在查找模板定义中使用的名称声明时,通常的查找规则(3.4.1、3.4.2)用于非依赖名称。依赖于模板参数的名称查找被推迟到知道实际的模板参数(14.6.2)。

这意味着,您必须告诉编译器,base_typeBase类中,这取决于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()
};
于 2013-02-07T11:36:40.863 回答
2

你总是可以这样做:

template<class C>
struct Base
{
};

template<class C>
struct Derived : public Base<C>
{
   typedef Base<C> base_type;  // define here

   Derived() : base_type() {}
};

Derived如果您将在...中引用基本类型是有道理的

于 2013-02-07T11:48:38.903 回答