dimanche 17 janvier 2021

Need help understanding std::forward

In the article Perfect forwarding and universal references in C++ I have one moment that I don't get. In paragraph Solving perfect forwarding with std::forward first case I understand, but second no.

The other case to handle is:

wrapper(42, 3.14f);
Here the arguments are rvalues, so T1 is deduced to int. We get the call func(forward<int>(e1), ...). Therefore, forward is instantiated with int and we get this version of it [3]:

int&& forward(int&& t) noexcept {
    return static_cast<int&&>(t);
}

Wrapper is

template <typename T1, typename T2>
void wrapper(T1&& e1, T2&& e2) {
    func(forward<T1>(e1), forward<T2>(e2));
}

for forward author said that this overload is used in this case

template<class T>
T&& forward(typename std::remove_reference<T>::type& t) noexcept {
  return static_cast<T&&>(t);
}

So after calling wrapper(42, 3.14f); we have

void wrapper(int&& && e1, float&& && e2) {
        func(forward<T1>(e1), forward<T2>(e2));

which is deduced to

void wrapper(int e1, float e2) {
        func(forward<int>(e1), forward<float>(e2));

then calling one of forward. as it's forward(typename std::remove_reference::type& t) we still have

int&& forward(typename std::remove_reference<int>::type& t) noexcept 
-->

int&& forward(typename int& t) noexcept 

So it's again

return static_cast<int& &&>(t);

which will return int&. But we should get int&& in this example. So I obviously not understanding something. For me it seems that typename std::remove_reference::type& t will always return reference, so forward's return will always be return static_cast<T& &&>(t); Need help, please.

Aucun commentaire:

Enregistrer un commentaire