I try to implement a CRTP with templated class and I have an error with the following example code :
#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;
}
I do not understand what causes this problem nor how to fix it.
In fact my goal is that the CRTP class have to know the template arguments of the derived class WITHOUT passing them as template argument of the CRTP class.
Do you have any ideas how to implement this?
EDIT (relating to the first first) : My CRTP class has to be able to handle derived classes with different number of template parameters
The problem is that MyClass
is incomplete in its own base class list, where you instantiate Crtp<MyClass>
. But instantiating Crtp<MyClass<...>>
requires instantiating Traits<MyClass<...>>
which then requires instantiating MyClass<...>::type
which is impossible because it's incomplete. You have a circular dependency.
In fact my goal is that the CRTP class have to know the template arguments of the derived class
That can be done using a partial specialzation and a template-template-parameter, like so:
#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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With