我试图用模板化类实现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类必须能够处理具有不同数量模板参数的派生类
问题是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;
}