【问题标题】:std::move return and input reference argumentstd::move 返回和输入引用参数
【发布时间】:2017-05-07 01:02:17
【问题描述】:

(A)

std::string doNothing(const std::string&& s)
{
  return std::move(s);
}

(B)

std::string doNothing(const std::string& s)
{
  return std::move(s);
}

(测试)

const std::string str = "aaaaaa";
const auto str2 = doNothing(str);

两个问题:

  1. (A)和(B)有区别吗?
  2. 在(测试)中:str 是未定义的吗?移到 str2 后?

【问题讨论】:

标签: c++ c++11 reference move-semantics


【解决方案1】:

std::move 将(非常量)右值引用作为参数。所以你不能将它直接绑定到 const 任何东西,无论是否是右值。因此,在 (A) 和 (B) 中,当您调用 std::move 时,它会生成一个未命名的临时副本并移动它。

因此,str 永远不会被移出,也不会受到任何影响。

要在不复制的情况下删除const,您需要一个明确的const_cast。如果你这样做了,你会得到明显的未定义行为。

【讨论】:

    【解决方案2】:
    1. 它们是不同的。在一种情况下,函数只接受 const 字符串类型的右值,它不接受左值,因为您不能将左值绑定到右值引用。 B case 中的函数同时接受右值和左值,因为您 可以 将右值绑定到 const 左值引用。在它们的体内它们是等价的,除非你在做 decltype(参数)。
    2. 再次,有 std::string( const std::string & ) 复制构造函数,可以接受右值字符串对象(std::move( s ) 返回 const std::string && 并发生复制)。李>

    【讨论】:

      【解决方案3】:

      对于给定的测试代码,情况有所不同,因为A 无法编译,而B 可以编译。

      如果A 右值引用无法绑定到左值。

      如果B 函数返回字符串的副本。将 std::move 与 const 引用一起使用仍会产生 const 引用。

      【讨论】:

      • 我没有看到任何关于 A 的信息,这会导致它无法编译。 const std::string&& 有效。奇怪而无用,但有效。
      • @MooingDuck 右值引用不能绑定到左值。 Link to MCVE
      • 啊,我明白误会了。 A 编译得很好。是 caller 编译失败。调用者必须将参数转换为const T&& 才能调用A
      猜你喜欢
      • 2017-10-19
      • 2014-04-15
      • 1970-01-01
      • 1970-01-01
      • 2013-04-05
      • 1970-01-01
      • 2018-03-21
      • 2015-05-10
      相关资源
      最近更新 更多