【问题标题】:Should std::move drop constness?std::move 应该放弃常量吗?
【发布时间】:2013-02-06 20:31:31
【问题描述】:

下面的代码在MSVC2010上编译运行,应该吗?

const std::string s = "foo";
std::string s2(std::move(s));

我明白为什么这可能不会破坏任何东西,因为如果我采用 s 的内部结构,我必须知道没有人会使用它,所以我放弃 const 并不重要。但是,编译器在 ROM 中(在嵌入式应用程序中)在哪里实现 const 对象呢?此举会变成副本吗?还是 MSVC 应该给我一个错误?

【问题讨论】:

  • 可能由于一些优化而编译?
  • @icepack 不,编译,特别是检查 const 正确性等。在优化之前。
  • @icepack 优化的黄金法则是 as-if 规则。编译器不能进行优化,因为它们的行为就像没有应用它们一样(就可观察的行为和语言规定的规则而言)。

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


【解决方案1】:

我认为std::move(T const&) 只是返回T const &&。这意味着,它实际上不会被移动(因为移动赋值运算符/构造函数与参数类型不匹配)。

发生的情况是,采用T const& 的构造函数匹配lvalue变量类型为T const &&),因此,移动降级为复制。

【讨论】:

  • @AndyProwl 似乎每次我在这里问一些问题时,你都会在那里回答:) 你就像守护天使的书呆子形式;)
  • @KerrekSB 虽然没有临时的(引用不是对象)。但是std::move(...) 是一个xvalue,const& 可以绑定xvalues。
  • PorkyBrain/@ArneMertz 将其浓缩成一条推文是一项挑战:twitter.com/sehetw/status/304587287046541312
  • @KerrekSB 是的,或多或少。 xvalues 既是 glvalues 又是 rvalues,因此它们可以绑定到 rvalue refs 或 lvalue refs (但在解决重载时首选 IIRC rvalue refs,因此首先选择它们)。
  • @R.MartinhoFernandes 一个右值(包括一个 xvalue)不会绑定到一个左值引用,除非它是一个 const 的左值引用。
【解决方案2】:

这和

没有区别
const std::string f() { return "foo"; }
std::string s2 = f();

这曾经是推荐的 C++03,并且委员会在引入右值引用时没有破坏此代码。它只是降级为副本。

【讨论】:

  • 与隐式移动情况进行了很好的比较。 +1
  • 怎么没有什么不同?在 OP 的帖子中,s2 是使用(强制转换的)右值引用构造的,而在这个 s2 中,s2 来自右值本身。
  • @texasbruce:在 OP 中,没有演员表。 std::move 是一个函数,就像本例中的 f() 一样。因此,在这两种情况下,s2 都使用函数本身的返回值进行初始化。
猜你喜欢
  • 1970-01-01
  • 2013-08-06
  • 1970-01-01
  • 1970-01-01
  • 2015-06-04
  • 2018-10-18
  • 2012-06-12
  • 1970-01-01
  • 2012-10-24
相关资源
最近更新 更多