3

In C++, it seems that a parameter may be normally expanded with ... directly after the parameter pack's name. For example,

template <class... Tys>
void function(Tys... params) {
    function(params...);
}

However, when using std::forward, the ... goes seemingly after the parameter pack's name. For example,

template <class... Tys>
void function(Tys... params) {
    function(std::forward<Tys>(params)...); // The '...' is outside the parenthesis of 'params'
}

My question is why is there a difference? Why is the following code incorrect?

template<class... Tys>
void function(Tys... params) {
    function(std::forward<Tys>(params...));
}

At what point in the parameter pack expanded? I probably am not fully understanding how std::forward works or how it forwards arguments perfectly.

I appreciate any answers!

Drake Johnson
  • 640
  • 3
  • 19
  • 1
    Related reading for understanding forwarding: [Advantages of using forward](https://stackoverflow.com/q/3582001/10239789) – TrebledJ Apr 08 '20 at 03:10

1 Answers1

6

The ... applies to the thing on its left.

  • function(params...)

    expands to

    function(param1, param2, ..., paramN).

  • function(std::forward<Tys>(params)...)

    expands to

    function(std::forward<Tys1>(param1), std::forward<Tys2>(param2), ..., std::forward<TysN>(paramN))

  • function(std::forward<Tys>(params...))

    expands to

    function(std::forward<Tys>(param1, param2, ..., paramN))

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770