使用CRTP时,在基类中使用非模板派生类的typedef
Using typedefs of a non-template derived class in the base class when using CRTP
我使用CRT模式,希望基类从派生类中看到typedef
。在这篇文章中,@James McNellis建议使用base_traits
类来实现这一点,并且效果很好。但在那篇文章中描述的情况下,派生类本身就是一个模板。当派生类不是模板时,此方法在VS2010中不起作用。
template <class D>
struct base_traits;
template <class D>
struct base
{
typedef typename base_traits<D>::value_t value_t;
};
struct derived : base<derived>
{
typedef typename base_traits<derived>::value_t value_t;
};
template<>
struct base_traits<derived>
{
typedef int value_t;
};
上面的代码给出了很多错误。第一个是:
错误C2027:使用未定义的类型"base_traits "
在CCD_ 3类的typedef的行上。
base_traits<derived>
必须在使用前声明和定义,因为它是base<derived>
的隐式安装所必需的(下面,我转发声明的derived
):
template <class D>
struct base_traits;
template <class D>
struct base
{
typedef typename base_traits<D>::value_t value_t;
};
struct derived;
template<>
struct base_traits<derived>
{
typedef int value_t;
};
struct derived : base<derived>
{
typedef base_traits<derived>::value_t value_t;
};
int main(void)
{
derived d;
}
实时演示
§14.7.3[温度解释规范]/p7:
函数显式专用化声明的位置模板、类模板、变量模板、的成员函数类模板,类模板的静态数据成员,成员类模板的类、类模板的成员枚举,类模板的成员类模板,成员函数模板类模板的静态数据成员模板,类模板的成员模板的成员函数,成员非模板类的成员模板的函数,静态数据非模板类的成员模板,的成员函数模板类模板的成员类等,以及局部类模板、变量模板的专门化声明,非模板类的成员类模板,静态数据成员非模板类的模板,类的成员类模板模板等会影响程序是否根据显性专业化的相对定位声明及其在翻译单元中的实例化点如上文和下文所述撰写专业文章时小心它的位置;或者将其编译将是一种尝试以点燃它的自焚
特别是(§14.7.3[温度解释规范]/p6),
如果一个模板[…]是显式专门化的,那么该专门化应在首次使用该专业之前声明会导致在每个发生这种使用的翻译单位;没有诊断必需。如果程序没有为显式专门化和[…]专门化在某种程度上被使用这将导致发生隐式实例化[…],程序格式不正确,不需要诊断。
显式专门化base_traits<derived>
必须在定义derived
之前声明和定义,否则从base<derived>
继承和使用base_traits<derived>::value_t
都会触发隐式实例化。因此:
template <class D>
struct base_traits;
template <class D>
struct base
{
typedef typename base_traits<D>::value_t value_t;
};
struct derived;
template<>
struct base_traits<derived>
{
typedef int value_t;
};
struct derived : base<derived>
{
typedef base_traits<derived>::value_t value_t;
};
- C++:TypeDef使用元组
- 为什么使用 "this" 指针调用派生成员函数?
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 在派生函数中指定void*参数
- 如何通过派生类函数更改基类中的向量
- 如何委托派生类使用其父构造函数?
- 如何使用单独文件中的派生类访问友元函数对象
- 派生类销毁的最佳实践是什么
- 如何使用基类指针引用派生类成员
- 派生类是否可以在抽象工厂设计模式中具有数据成员
- 使用基类指针创建对象时,缺少派生类析构函数
- 如何引用基类的派生类?
- 存储模板类型以强制转换回派生<T>
- 需要从 istream 和 ostream 派生 iostream
- 为什么通过 CRTP 访问派生类中的 typedef 时会出现错误
- 在派生类中使用 typedef/using from 模板化基类
- 如何使用包含不同typedef枚举的派生类模板设置构造函数初始化列表
- 使用CRTP时,在基类中使用非模板派生类的typedef
- 访问派生类模板中的基类typedef
- C++静态多态性 (CRTP) 并使用派生类中的 typedef