2

This is the example from cppreference. I don't understand how the pattern get expanded.

template<typename ...Ts, int... N> void g(Ts (&...arr)[N]) {}
int n[1];
g<const char, int>("a", n); // Ts (&...arr)[N] expands to 
                            // const char (&)[2], int(&)[1]

Note: In the pattern Ts (&...arr)[N], the ellipsis is the innermost element, not the last element as in all other pack expansions.

Question 1: what is arr?

Question 2: n is a int array, does it match to int...N?

Question 3: How come it can expand to const char (&)[2], int(&)[1]

Jerry
  • 1,704
  • 5
  • 20
  • 40
  • See any number of questions about pack expansion, like [this one](https://stackoverflow.com/a/26767333/2069064) – Barry Jul 18 '17 at 01:05
  • To address question 2: `Ts` is a type pack for the array types, and `N` is an int pack for the array dimensions, so `n` provides the type `int` into the `Ts` pack, and the dimension 1 into the `N` pack. – cdhowie Jul 18 '17 at 02:17
  • Ugly syntax of reference to C-Array (`int (&a)[42]` ) with variadic template. – Jarod42 Jul 18 '17 at 09:53
  • For 3: "a" is equivalent to { 'a', 0 } – Caleth Jul 18 '17 at 10:21

1 Answers1

3

Whereas

template <typename ...Ts> void f(Ts&...arr);

is mostly equivalent to

template <typename T0, typename T1, .., typename TN>
void f(T0& arr0, T1& arr1, .., TN& arrN);

for any N.

In the same way,

template <typename ...Ts, int... Ns> void g(Ts (&...arr)[Ns]);

would be equivalent to

template <typename T0, typename T1, .., typename TN, int N0, int N1, .. int NN>
void g(T0 (&arr0)[N0], T1 (&arr1)[N1], .., TN (&arrN)[NN]);

and type T (&)[N] is a reference to C-array of size N with element of type T

int n[1]; is trivially of type int [1].

"a" is of type const char[2] ({'a', '\0'}).

Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • A: void g(T0 (&arr0)[N0], T1 (&arr1)[N1], .., TN (&arrN)[NN]); B: g("a", n); I can understand your answer, but how does A match to B? Thanks – Jerry Jul 18 '17 at 18:50
  • So if T0 = const char and T1 = int, what are N0 and N1? Where do the 2 and 1 come from in the expanded result? – Jerry Jul 18 '17 at 18:56
  • @Jerry: Edited. `"a"` is not `const char*` but `const char[2]`. – Jarod42 Jul 18 '17 at 19:05
  • Is this a specific structure of the command? Like why can't `void g(Ts... (&)[Ns...])` or `void g(Ts (&)[Ns]...)` work? Can you explain how both the options are wrong. I'm pretty new to it. – Dhruv Oct 05 '22 at 15:09
  • @Dhruv: It is mostly a syntax/grammar issue; syntax for c-array (and function) is *"ugly"*.BTW, `Ts... (&)[Ns...]` would have 2 distinct packs :/ . Using alias might help when working with c-array: `template using CArray = T[N];` then `CArray&...arr` is the way to go. – Jarod42 Oct 05 '22 at 17:13