abelenky
abelenky

Reputation: 64672

Template Meta-programming, with Variadic Templates: compiler error

I'm attempting variadic template meta programming for the first time and consistently getting a compiler error that I have not been able to track down.

I'm following the "tuple" example on this page (although I'm calling my object an ItemSet)

The ItemSet part compiles just fine:

template<typename...Ts> class ItemSet { };

template<typename item_T, typename ...Ts>
class ItemSet<item_T, Ts...> : public ItemSet<Ts...>
{
public:
    ItemSet(item_T t, Ts... item_types) : ItemSet<Ts...>(item_types...), tail(t) { }

protected:
    item_T tail;
};





template <typename...M> struct type_holder;

template<typename T, typename ...M>
struct type_holder<0, ItemSet<T, M...>>
{                          // ERROR: M parameter pack expects a type template argument.
    typedef T type;
};

template <int k, typename T, typename ...M>
struct type_holder<k, ItemSet<T, M...>>
{
    typedef typename type_holder<k - 1, ItemSet<M...>>::type type;
};




int main()
{
    ItemSet<int, string, string, double> person(0, "Aaron", "Belenky", 29.492);
}

However, in the commented out code, I get the compiler error at the declaration of type_holder. I've tried a bunch of variations on the same syntax, but always with the same issue.

I'm using Microsoft Visual Studio 2013, which is supposed to have full support for Template programming and Variadic Templates.

Do you understand what the compiler error is, and can you explain it to me?

Upvotes: 1

Views: 396

Answers (1)

Dietmar K&#252;hl
Dietmar K&#252;hl

Reputation: 153792

The immediate problem is that you are defining a specialization of type_holder without a general template. In addition, there is a simple typo (typeholder instead of type_holder). Fixing these two issues makes it compile with other compilers:

template <int, typename T>
struct type_holder;

template <int k, typename T, typename ...M>
struct type_holder<k, ItemSet<T, M...>>
{
    typedef typename type_holder<k - 1, ItemSet<M...>>::type type;
};


template<class T, class ...M>
struct type_holder<0, ItemSet<T, M...>>
{
    typedef T type;
};

The error emitted by the compilers you used isn't particular helpful. I'd recommend keeping a few C++ compilers around just to test template code with (I'm typically using gcc, clang, and Intel's compiler).

Upvotes: 6

Related Questions