【问题标题】:Perfect Forward using std::forward vs RefRefCast使用 std::forward 与 RefRefCast 完美转发
【发布时间】:2020-10-23 13:06:23
【问题描述】:

感谢您对理解 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&& 参数。 那有必要吗? 比演员阵容更好吗?

【问题讨论】:

  • eli.thegreenplace.net/2014/… 还具有两个模板函数实现
  • 更重要的是,标准将std::forward&lt;T&gt;(x)的返回值定义为static_cast&lt;T&amp;&amp;&gt;(x)

标签: c++ rvalue perfect-forwarding function-templates


【解决方案1】:

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

但是,除此之外还有一点优势。在绝大多数情况下,std::forward 的左值变体将被调用,因为每个命名变量都是一个左值。但在某些特殊情况下,您可能希望转发函数调用结果(例如std::move)。在这种情况下,如果 t 是左值,则转换 static_cast&lt;T&amp;&amp;&gt;(std::move(t)) 将不起作用,因为禁止从右值转换为左值。

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

【讨论】:

    猜你喜欢
    • 2014-01-04
    • 1970-01-01
    • 2015-09-07
    • 2015-04-11
    • 1970-01-01
    • 2019-04-11
    • 2020-06-07
    • 2011-11-07
    • 2012-06-23
    相关资源
    最近更新 更多