C ++ std :: forward <T> vs static_cast <T>

From what I understand, std::forward<T>(x) equivalent to static_cast<T&&>(x) .

But from what I saw, static_cast<T>(x) seems to do the same thing as can be seen in the following code

So my question is: why is std::forward<T> implemented as static_cast<T&&>(x) rather than static_cast<T>(x) if both have the same effect?

+6
source share
3 answers

Since perfect forwarding allows you to transfer both references to the r-value and references to the l-value. This is done by writing off links :

 T = int --> T&& = int&& T = int& --> T&& = int& && = int& T = int&& --> T&& = int&& && = int&& 

In your example with static_cast<T> you simply lose references to the r-value. It works great for primitive types (since an int transfer usually copies the value of the CPU register), but terrible for complex types, because it leads to the creation of a temporary object through ctors copies.

+10
source

If T&& is a rvalue reference, then T is a value, then static_cast<T> makes a copy not a rvalue reference.

This copy will link to rvalue links (just like a link), but you can copy / move ctors without having to call, and this is not a candidate for elite.

static_cast<T&&> will only be shown with a link to rvalue.

Otherwise they are identical.

+2
source

I agree with Jakk, but it's worse than that.

 void foo(const std::vector<int> &vec); template<typename T> void callFoo(T &&data) { foo(static_cast<T>(data)); } int main() { callFoo(std::vector<int>{/*...*/}); } 

This always creates a copy. The vector does not move because data , as an expression, is an lvalue of type std::vector<int> , although the replaced type is std::vector<int>&& . Note that T is std::vector<int> , not std::vector<int> && . The moral of the story: use the standard library, it does the right thing, and the name forward also reflects the intention much better than static_cast<something> .

0
source

All Articles