我使用CRT模式并希望基类从派生类中查看typedef
s。在this post @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:使用未定义类型&#39; base_traits
在base
类的typedef。
答案 0 :(得分:6)
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;
}
答案 1 :(得分:4)
§14.7.3[temp.expl.spec] / p7:
为函数放置显式特化声明 模板,类模板,变量模板,成员函数 类模板,类模板的静态数据成员,成员 类模板类,类模板的成员枚举, 类模板的成员类模板,成员函数模板 类模板,类模板的静态数据成员模板, 类模板的成员模板的成员函数,成员 非模板类的成员模板的功能,静态数据 非模板类的成员模板,成员函数模板 类模板的成员类等,以及部分的放置 类模板的特化声明,变量模板, 非模板类的成员类模板,静态数据成员 非模板类的模板,类的成员类模板 模板等可以影响程序是否格式正确 到显式专业化的相对定位 声明及其在翻译单元中的实例化要点 如上下文所述。 撰写专业时,请 小心它的位置;或者使它编译将是这样的试验 点燃自焚。
特别是(§14.7.3[temp.expl.spec] / 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;
};