【问题标题】:Does std::move need to be combined with std::forward when using forwarding references?使用转发引用时,std::move 是否需要与 std::forward 结合使用?
【发布时间】:2015-01-07 02:06:51
【问题描述】:

在使用通用引用时,std::move 是否需要与 std::forward 结合使用?比如下面两段代码哪个是正确的?

void bar(auto && x) {
    auto y(std::move(std::forward<decltype(x)>(x)));
}

void bar(auto && x) {
    auto y(std::move(x));
}

基本上,我想将 x 的内存移动到 y 中,我不在乎它是左值引用还是右值引用。当然,我不希望这里有 const 值。

【问题讨论】:

  • 没有。只使用其中之一。
  • 它们都等价于auto y(std::move(x)),它转发,只是转换为右值引用。请记住,std::forward&lt;T&gt;() 是对右值或左值引用的条件转换(取决于值类别),而std::move() 是对右值引用的无条件转换。

标签: c++ c++14


【解决方案1】:

如果您想不管参数的值类别移动,move 就足够了。
forward 在这种情况下是多余的,因为move(forward(x)) 始终是右值,无论forward(x) 是什么。

如果您只想根据bar 的参数是否为右值来移动,则应单独使用forward,它会传播值类别。

【讨论】:

  • 现在,尽管对forward 的调用是多余的,但move 的原型在技术上不是一个通用参考,它暗示了前进吗?
  • @wyer33 把move 想象成一个函数,它返回一个引用其参数的右值。并将forward 想象成一个函数,它返回一个引用其参数的左值或右值引用。 forward 在表达式中产生的差异,如果有的话,无论如何都会被 move 根除。
【解决方案2】:

/!\当心/!\

使用std::move 作为通用参考可能是一个非常糟糕的主意,强烈建议避免使用:

auto name = getName(); // std::string getName();
bar(name);
// 'name' value has been moved... And its value now is unknown, empty at best.

move(forward(x)) 风格不好,不应该使用。

您应该将std::move 用于右值引用,将std::forward 用于通用引用。参照。正式定义。

auto&amp;&amp; 是一个通用引用,因此你应该写的是:

void bar(auto&& x) {
    auto y(std::forward<decltype(x)>(x));
}

【讨论】:

  • auto 作为函数参数?你使用的是哪个版本的 C++,C++21?
  • Six60r:它是一个缩写函数,还不是标准的一部分,@ViktorSehr fyi
猜你喜欢
  • 2015-05-03
  • 2016-07-08
  • 1970-01-01
  • 2013-06-25
  • 2017-07-08
  • 2020-10-23
  • 1970-01-01
  • 1970-01-01
  • 2012-10-24
相关资源
最近更新 更多