mercredi 22 février 2017

Perfect Fowarding and std::forward

I am currently trying to figure out how exactly perfect forwarding works. I have written a piece of example code that as far as I know performs perfect forwarding as it's supposed to be:

void whatIsIt(std::vector<int>&& variable)
{
  std::cout << "rvalue" << std::endl;
}

void whatIsIt(std::vector<int>& variable)
{
  std::cout << "lvalue" << std::endl;
}

template <class T>
void performPerfectForwarding(T&& variable)
{
  whatIsIt(std::forward<T>(variable));
}

int main(int argc, char** argv)
{
  std::vector<int> lvalue;
  performPerfectForwarding(lvalue);
  performPerfectForwarding(std::move(lvalue));

  return 0;
}

Calling the function performPerfectForwarding with an lvalue makes it call the corresponding overload of whatIsIt and the same applies for calling it with an rvalue. Consequently, the output generated by this code is:

lvalue
rvalue

However, I was asking myself what the following versions of the function performPerfectForwarding would do:

1.

template <class T>
void performPerfectForwarding(T& variable)
{
  whatIsIt(std::forward<T>(variable));
}

2.

template <class T>
void performPerfectForwarding(T variable)
{
  whatIsIt(std::forward<T>(variable));
}

They both output:

rvalue
rvalue

Now, my questions are: What would these two alternative versions do and would they make sense in any possible context? How do the reference collapsing rules apply in these cases compared to how they apply in the aforementioned "correct" version?

Aucun commentaire:

Enregistrer un commentaire