[英]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;
}
§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.