CRTP + Traits Class: "no type named ..."

I am trying to implement CRTP with a template, and I have an error with the following code example:

#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, and how to fix it.

Actually my goal is that the CRTP class needs to know the template arguments of the derived WITHOUT class, passing them as the template argument for the CRTP class.

Do you have any idea how to implement this?

EDIT (applies to the first): My CRTP class should be able to handle derived classes with a different number of template parameters

+6
source share
1 answer

The problem is that MyClass is incomplete in its own list of base classes, where you create an instance of Crtp<MyClass> . But an instance of Crtp<MyClass<...>> requires an instance of Traits<MyClass<...>> , which then requires an instance of MyClass<...>::type , which is not possible because it is incomplete. You have a circular addiction.

Actually my goal is that the CRTP class needs to know the template arguments of the derived class

This can be done using a partial specialzation and a template-template parameter, for example:

 #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; } 
+7
source

Source: https://habr.com/ru/post/922048/


All Articles