据我所知,std::forward<T>(x)
相当于static_cast<T&&>(x)
。C++ std :: forward <T> vs static_cast <T>
但是从我所看到的,static_cast<T>(x)
似乎做同样的事情,因为可以在下面的code
我的问题可以看出因此也是为什么std::forward<T>
作为static_cast<T&&>(x)
实现的,而不是static_cast<T>(x)
,如果两者都具有相同的影响?
据我所知,std::forward<T>(x)
相当于static_cast<T&&>(x)
。C++ std :: forward <T> vs static_cast <T>
但是从我所看到的,static_cast<T>(x)
似乎做同样的事情,因为可以在下面的code
我的问题可以看出因此也是为什么std::forward<T>
作为static_cast<T&&>(x)
实现的,而不是static_cast<T>(x)
,如果两者都具有相同的影响?
因为完美转发允许通过r值参考和l值参考。这是通过reference collapsing完成:
T = int --> T&& = int&&
T = int& --> T&& = int& && = int&
T = int&& --> T&& = int&& && = int&&
在你的榜样与static_cast<T>
你只是失去r值引用。它适用于原始类型(因为传递int
通常会复制一个CPU寄存器值),但对于复杂类型会很糟糕,因为它会导致通过复制ctors创建临时对象。
如果T&&
是一个rvalue引用,那么T
是一个值,则static_cast<T>
使得拷贝不是右值参考。
该副本将绑定到右值引用(就像引用),但复制/移动ctors可能被不必要地调用,并且它不是elision的候选人。
static_cast<T&&>
将同时只投到一个右值引用。
它们在其他方面是相同的。
我同意雅克,但它比这更糟糕。
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>{/*...*/});
}
这将始终创建副本。载体是而不是,因为data
作为表达式是std::vector<int>
类型的左值,即使取代类型为std::vector<int>&&
。请注意,T
是std::vector<int>
,而不是std::vector<int> &&
。故事的道德:使用标准库,它做的是正确的事,并且名称forward
也比static_cast<something>
更好地捕捉了意图。
您没有尝试'int&'。 – Quentin
@Quentin在这种情况下,它总是返回一个左值。 – Mikrosaft
'static_cast'会创建一个右值的副本 –