8

Consider an alias based on a variadic template, that uses its first element in an expansion expression:

template<typename T, typename... Ts>
using AllSame = std::conjunction<std::is_same<T, Ts>...>;

If we use this alias by passing the first element separately, the code compiles fine:

template<typename T, typename... Ts>
using X = AllSame<T, Ts...>;

But simply passing an entire pack doesn't compile:

template<typename... Ts>
using X = AllSame<Ts...>;

Here is the compile error:

error: pack expansion argument for non-pack parameter 'T' of alias template 'template<class T, class ... Ts> using AllSame = typename std::enable_if<std::is_same<bool_pack<true, std::is_same<T, Ts>::value ...>, bool_pack<std::is_same<T, Ts>::value ..., true> >::value>::type'

Why does the call site have to pass in the first parameter separately, and not just pass in the whole pack directly?

Here is some code to reproduce the problem.

max66
  • 65,235
  • 10
  • 71
  • 111
Jonathan Boccara
  • 421
  • 1
  • 3
  • 7
  • 1
    Interesting to note, if you change `AllSame` to be a template class instead of a template alias, `X` works fine. – user975989 Feb 08 '20 at 22:13
  • Short answer: class templates can be (partially) specialized, this is why this works for them. Template aliases cannot be specialized, there is no pattern-matching involved to find a specialization. – lisyarus Feb 08 '20 at 22:18
  • 1
    Intriguing question... I suppose it's a question for language layers (tag added) – max66 Feb 08 '20 at 22:18

0 Answers0