how do I fix this c++ typelist template compile error?
(from reading chapter 3 of modern c++ design)
typelist.hpp:
class NullType {};
struct EmptyType {};
template <class T, class U>
struct Typelist
{
typedef T Head;
typedef U Tail;
};
#define TYPELIST_1(T1) Typelist<T1, NullType>
#define TYPELIST_2(T1, T2) 开发者_C百科Typelist<T1, TYPELIST_1(T2) >
#define TYPELIST_3(T1, T2, T3) Typelist<T1, TYPELIST_2(T2, T3) >
#define TYPELIST_4(T1, T2, T3, T4) Typelist<T1, TYPELIST_3(T2, T3, T4) >
#define TYPELIST_5(T1, T2, T3, T4, T5) Typelist<T1, TYPELIST_4(T2, T3, T4, T5) >
#define TYPELIST_6(T1, T2, T3, T4, T5, T6) Typelist<T1, TYPELIST_5(T2, T3, T4, T5, T6) >
namespace TL
{
template <class TList> struct Length;
template <> struct Length<NullType>
{
enum { value = 0 };
};
template <class T, class U>
struct Length< Typelist<T, U> >
{
enum { value = 1 + Length<U>::value };
};
template <class Head, class Tail>
struct TypeAt<Typelist<Head, Tail>, 0>
{
typedef Head Result;
};
template <class Head, class Tail, unsigned int i>
struct TypeAt<Typelist<Head, Tail>, i>
{
typedef typename TypeAt<Tail, i-1>::Result Result;
};
}
main.cpp
#include "typelist.hpp"
Typelist<int, double> foo;
int main() {
}
g++ main.cpp
typelist.hpp:37: error: ‘TypeAt’ is not a template
typelist.hpp:43: error: type/value mismatch at argument 2 in template parameter list for ‘template<class Head, class Tail> struct TL::TypeAt’
typelist.hpp:43: error: expected a type, got ‘i’
Why do I get this error? How do I fix this?
Looks like you're missing a forward declaration.
This is a partial specialization:
template <class Head, class Tail>
struct TypeAt<Typelist<Head, Tail>, 0>
But the compiler has no idea what it's a specialization of. Add this before it:
template <class List, unsigned Index>
struct TypeAt;
This let's the compiler know: "There is a class TypeAt
which has two template parameters." So now when you specialize it, the compiler knows what class you're talking about.
Note, your usage of Typelist
is incorrect. These algorithm's are sentinel-terminated. This means, like C-strings, they expect the data to be concluded with a special value. In our case, this is NullType
.
So, take Éric's advice. (i.e. hint: if you found his answer helpful, up-vote it.)
Typelist is designed to be used recursively: It expects its second templater parameter to be either another Typelist, or NullType (signaling the end of recursion).
To define foo, you should write:
TYPELIST_2(int, double) foo;
or, if you want to avoid macros:
Typelist<int, Typelist<double, NullType> > foo;
精彩评论