非常感谢您帮助理解 std::forward 实现。
模板函数中 std::forward 和标准转换为 T&& 之间有什么区别? 至少在这个例子中,它们似乎都正确地完成了转发工作。 LValue 被转发到 LValue 重载,RValue 被转发到 RValue 重载。
struct DemoPerfectForwardVsRefRefCast
{
void overloaded(int const &arg) { std::cout << "receive by lvalue\n"; }
void overloaded(int && arg) { std::cout << "receive by rvalue\n"; }
template< typename t >
void forwarding(t && arg) {
std::cout << "via std::forward: ";
overloaded(std::forward< t >(arg)); // forwards correctly
std::cout << "via && cast: ";
overloaded(static_cast<t&&>(arg)); // seems to also forward correctly
}
void demo()
{
std::cout << "initial caller passes rvalue:\n";
forwarding(5);
std::cout << "initial caller passes lvalue:\n";
int x = 5;
forwarding(x);
}
};
通用引用+引用折叠+静态转换为T&&就足够了吗?
在 Visual Studio 2017 中,std::forward 的定义实现方式不同,有两个模板函数,一个带有 T& 参数,另一个带有 T&& 参数。 有必要吗? 是不是比单纯的演员阵容更好? 我对他们的评论感到很困惑
// forward an lvalue as either an lvalue or an rvalue
// forward an rvalue as an rvalue
总之,为了转发变量,您可以使用简单的强制转换。引入函数的原因主要是为了让代码更简洁。
然而,除此之外还有一点优势。在绝大多数情况下,将调用
std::forward
的左值变体,因为每个命名变量都是左值。但在某些特殊情况下,您可能想要转发函数调用结果(例如std::move
)。在这种情况下,如果 t 是左值,则转换 static_cast<T&&>(std::move(t))
将不起作用,因为禁止从右值转换为左值。
我认为第二种用例极其罕见,但应该涵盖这种可能性。