0

I wrote a small using statement to have easy access to the types of a variadic template parameter pack.

template<size_t index, typename args...>
using get = std::tuple_element<index, std::tuple<args...>>::type;

But compiling this with clang (3.5.0) or gcc (4.9.0) fails. Here is the error output of clang:

error: expected ',' or '>' in template-parameter-list template<size_t index, typename args...>
                                                                                          ^

Is the using statement not combinable with variadic templates? Or am I doing something wrong?

Constructor
  • 7,273
  • 2
  • 24
  • 66
mic
  • 821
  • 6
  • 18
  • maybe `typename` after `=`? Because `::type` is dependent on the template parameters – leemes Jun 22 '14 at 18:58
  • 1
    I VTCd for typo because it's `typename... args`, not `typename args...`, but yeah, `typename` is required as well. – chris Jun 22 '14 at 18:58
  • 1
    If you'd like the other half of the close vote, http://stackoverflow.com/questions/610245/where-and-why-do-i-have-to-put-the-template-and-typename-keywords – chris Jun 22 '14 at 19:05
  • Also, you find the exact solution in the example of the documentation of `std::tuple_element` at cppreference.com: http://en.cppreference.com/w/cpp/utility/tuple/tuple_element – leemes Jun 22 '14 at 19:05
  • The compiler output was not very helpful for the `typename... args` typo. So I was wondering about why this fails. But as it turns out I realy was "doing something wrong". – mic Jun 23 '14 at 05:59

2 Answers2

6

The ellipsis for the parameter pack needs to be after the typename (or class) keyword. It goes after the parameter name when you expand the pack.

template<size_t index, typename... args>
//                             ^^^
using get = typename std::tuple_element<index, std::tuple<args...>>::type;
//          ^^^^^^^^^

You're also missing the typename keyword which is needed when referring to a nested dependent type.

Praetorian
  • 106,671
  • 19
  • 240
  • 328
4

Two things are wrong in your code.

First, since the definition of std::tuple_element<...> depends on what ... is, you need to tell the compiler that ::type refers to a type name, hence you need typename in front of it.

Second, variadic template parameters have their ellipsis in between typename (or class) and the name of the pack, i.e. typename ...args instead of typename args....

So the fixed code is then:

template<size_t index, typename ...args>
using get = typename std::tuple_element<index, std::tuple<args...>>::type;
leemes
  • 44,967
  • 21
  • 135
  • 183