Uczę się TMP w C++ i jestem na etapie rekurencyjnego generowania klas za pomocą list typów. Taki koncept jest przedstawiony między innymi w książce "Modern Design in C++" Andrei Alexandrescu no i niby zdefiniowałem listę typów oraz szablon, który ma mi te klasy generować. Niemniej jednak przy próbie deklaracji obiektu o określonym typie wywala mi błąd:
incomplete type is not allowed
oraz
Error C2079 'obj' uses undefined class 'GenScatterHierarchy<TypeList<T,TypeList<std::basic_string<char,std::char_traits<char>,std::allocator<char>>,TypeList<double,make<>::type>>>,Holder>'
Co może być tego przyczyną? Czego mi brakuje, aby kompilator wygenerował mi hierarchię klas?
Kompiluje za pomocą MSVC na Visual Studio 2017.
Oto kod:
Lista typów:
struct null_t {};
template <typename T, typename U>
struct TypeList {
using head = T;
using tail = U;
};
template <typename ... Ts> struct make;
// Case: Normal recursion. Consume one type per call.
template <typename T, typename ... REST>
struct make<T, REST...> {
using type = TypeList<T, typename make<REST...>::type>;
};
// Case: Recursion abort, because the list of types ran empty
template <>
struct make<> { using type = null_t; };
template <typename ... Ts>
using make_t = typename make<Ts...>::type;
Szablon generujący hierarchię:
template <typename TypeList, template<class> typename Unit>
class GenScatterHierarchy;
template <typename T1, typename T2, template <class> typename Unit>
class GenScatterHierarchy<TypeList<T1,TypeList<T2, null_t>>, Unit>
: public GenScatterHierarchy<T1, Unit>
, public GenScatterHierarchy<T2, Unit>
{
};
template <typename AtomicType, template <class> typename Unit>
class GenScatterHierarchy
:public Unit<AtomicType>
{
};
template<template<class> typename Unit>
class GenScatterHierarchy<null_t, Unit>
{
};
No i main:
template <class T>
struct Holder {
T value_t;
};
using GeneratedType = GenScatterHierarchy<make_t<int, std::string, double>, Holder>;
int main()
{
GeneratedType obj; // tu błąd
system("pause");
return 0;
}