CRTP + Traits类:“没有命名的类型......”

时间:2012-08-03 12:39:20

标签: c++ templates crtp typetraits

我尝试使用模板化类实现CRTP,并且我在以下示例代码中出错:

#include <iostream>

template<class T> class Traits
{
    public:
        typedef typename T::type type; // <- Error
                                       // : "no type named 'type' in 'class MyClass<double, 3u, 3u>'
        static const unsigned int m_const = T::m_const;
        static const unsigned int n_const = T::n_const;
        static const unsigned int size_const = T::m_const*T::n_const;
};

template<class T0> class Crtp
{
    public:
        typedef typename Traits<T0>::type crtp_type;
        static const unsigned int size = Traits<T0>::size_const; // <- This is OK
};

template<typename TYPE, unsigned int M, unsigned int N>
class MyClass : public Crtp< MyClass<TYPE, M, N> >
{
    public:
        typedef TYPE type;
        static const unsigned int m_const = M;
        static const unsigned int n_const = N;
};

int main()
{
    MyClass<double, 3, 3> x;
    std::cout<<x.size<<std::endl;
    return 0;
}

我不明白导致这个问题的原因以及解决方法。

实际上我的目标是CRTP类必须知道派生类的模板参数,而不将它们作为CRTP类的模板参数传递。

您对如何实现这一点有什么想法吗?

EDIT(与第一个相关):我的CRTP类必须能够处理具有不同数量的模板参数的派生类

1 个答案:

答案 0 :(得分:7)

问题是MyClass在其自己的基类列表中不完整,您在其中实例化Crtp<MyClass>。但实例化Crtp<MyClass<...>>需要实例化Traits<MyClass<...>>,然后需要实例化MyClass<...>::type这是不可能的,因为它不完整。你有一个循环依赖。

  

实际上我的目标是CRTP类必须知道派生类

的模板参数

可以使用部分特殊化和模板模板参数来完成,如下所示:

#include <iostream>

template<typename T> class Crtp;

template<template<typename, unsigned, unsigned> class T, typename U, unsigned M, unsigned N>
class Crtp< T<U, M, N> >
{
    public:
        typedef U crtp_type;
        static const unsigned int size = M * N;
};

template<typename TYPE, unsigned int M, unsigned int N>
class MyClass : public Crtp< MyClass<TYPE, M, N> >
{
};

int main()
{
    MyClass<double, 3, 3> x;
    std::cout<<x.size<<std::endl;
    return 0;
}