使用 std::forward 与 RefRefCast 进行完美转发

问题描述 投票:0回答:1

非常感谢您帮助理解 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
c++ rvalue perfect-forwarding function-templates
1个回答
1
投票

总之,为了转发变量,您可以使用简单的强制转换。引入函数的原因主要是为了让代码更简洁。

然而,除此之外还有一点优势。在绝大多数情况下,将调用

std::forward
的左值变体,因为每个命名变量都是左值。但在某些特殊情况下,您可能想要转发函数调用结果(例如
std::move
)。在这种情况下,如果 t 是左值,则转换
static_cast<T&&>(std::move(t))
将不起作用,因为禁止从右值转换为左值。

我认为第二种用例极其罕见,但应该涵盖这种可能性。

© www.soinside.com 2019 - 2024. All rights reserved.