简体   繁体   English

使用CRTP时,在基类中使用非模板派生类的typedef

[英]Using typedefs of a non-template derived class in the base class when using CRTP

I'm using CRT pattern and want the base class to see typedef s from the derived class. 我正在使用CRT模式,并希望基类从派生类中查看typedef In this post @James McNellis suggested to do that using base_traits class and it works fine. 这篇文章中 @James McNellis建议使用base_traits类来做到这base_traits并且它工作正常。 But in the case described in that post the derived class itself is a template. 但是在该帖子中描述的情况下,派生类本身就是一个模板。 This approach does not work in VS2010 when the derived class is not a template. 当派生类不是模板时,此方法在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;
};

The above code gives lots of errors. 上面的代码提供了很多错误。 The first one is: 第一个是:

error C2027: use of undefined type 'base_traits 错误C2027:使用未定义类型'base_traits

on the line of the base class's typedef. base类的typedef的行上。

base_traits<derived> must be declared and defined prior it's usage since it is needed for the implicit instancation of base<derived> (below, I forward declared derived ) : 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;
}

Live demo 现场演示

§14.7.3 [temp.expl.spec]/p7: §14.7.3[temp.expl.spec] / p7:

The placement of explicit specialization declarations for function templates, class templates, variable templates, member functions of class templates, static data members of class templates, member classes of class templates, member enumerations of class templates, member class templates of class templates, member function templates of class templates, static data member templates of class templates, member functions of member templates of class templates, member functions of member templates of non-template classes, static data member templates of non-template classes, member function templates of member classes of class templates, etc., and the placement of partial specialization declarations of class templates, variable templates, member class templates of non-template classes, static data member templates of non-template classes, member class templates of class templates, etc., can affect whether a program is well-formed according to the relative positioning of the explicit specia 为函数模板,类模板,变量模板,类模板的成员函数,类模板的静态数据成员,类模板的成员类,类模板的成员枚举,类模板的成员类模板,成员函数放置显式特化声明类模板的模板,类模板的静态数据成员模板,类模板的成员模板的成员函数,非模板类的成员模板的成员函数,非模板类的静态数据成员模板,成员类的成员函数模板类模板等,以及类模板,变量模板,非模板类的成员类模板,非模板类的静态数据成员模板,类模板的成员类模板等的部分特化声明的放置,可以根据显式specia的相对位置来影响程序是否格式正确 lization declarations and their points of instantiation in the translation unit as specified above and below. 翻译单元中的lization声明及其实例化点,如上下文所述。 When writing a specialization, be careful about its location; 写专业时,要注意它的位置; or to make it compile will be such a trial as to kindle its self-immolation. 或者使它编纂将是一种试图点燃其自焚的试验。

In particular (§14.7.3 [temp.expl.spec]/p6), 特别是(§14.7.3[temp.expl.spec] / p6),

If a template [...] is explicitly specialized then that specialization shall be declared before the first use of that specialization that would cause an implicit instantiation to take place, in every translation unit in which such a use occurs; 如果模板明确专门化,则应在首次使用该特化之前声明该特化,这将导致在发生此类使用的每个翻译单元中发生隐式实例化; no diagnostic is required. 无需诊断。 If the program does not provide a definition for an explicit specialization and [...] the specialization is used in a way that would cause an implicit instantiation to take place [...], the program is ill-formed, no diagnostic required. 如果程序没有为显式特化提供定义,并且特殊化的使用方式会导致隐式实例化[...],则程序格式错误,无需诊断。

The explicit specialization base_traits<derived> must be declared and defined before the definition of derived , as otherwise both inheriting from base<derived> and using base_traits<derived>::value_t would trigger an implicit instantiation. 的显式特base_traits<derived>必须声明和定义之前定义derived ,因为否则从两个继承base<derived>和使用base_traits<derived>::value_t将触发一个隐含的实例化。 Thus: 从而:

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;
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 CRTP层级类的非模板基类 - Non-template base class for CRTP hierarcy class 将非模板基类向下转换为模板化派生类:是否可能? - Downcasting non-template base class to templated derived class: is it possible? 使用`this`作为指向CRTP中基类的派生类的指针 - Using `this` as a pointer to derived class in a base class in CRTP 继承的非模板类的范围问题(模板基,非模板派生) - Scope problems with inherited non-template class (template base, non-template derived) 从非模板基类派生的模板类:无法访问基类变量? - Template Class derived from Non-template base class: No access to base class variables? CRTP(奇怪的重复模板模式)使用通用基础模板类而不是派生类 - CRTP (Curiously Recurring Template Pattern) using a generic base template class instead of the derived class 如何使用非模板派生的 class 制作非类型模板基础 class - How to make a non-type template base class with non-template derived class 从模板派生类访问非模板基类虚函数 - accessing non-template base class virtual function from template derived class 如何将模板派生类的方法提取到非模板基类中 - how to extract template derived class's method into non-template base class 从基非模板类调用派生模板类方法 - Calling derived template class method from base non-template class
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM