【问题标题】:Why move on const objects work?为什么继续使用 const 对象?
【发布时间】:2014-07-17 12:52:22
【问题描述】:

我有一个简单的代码:

const std::vector<int> data = {1,2,3};
std::vector<int> data_moved=std::move(data);
for(auto& i:data)
    cout<<i;//output is 123

编译没有任何错误或警告!

而且似乎data 中仍有值!

移动一个 const 值似乎不正确,因为我们不能修改 const 对象那么该代码如何编译?!

【问题讨论】:

  • 哪个编译器?什么命令行标志?来吧。
  • 因为 const&& 也可以绑定到 const&。这是有效的行为。
  • @LightnessRacesinOrbit ideone.com/WIk6Dx
  • @omid:不,我的意思是,您的问题应该包括有关您正在使用的编译器以及如何使用它的详细信息。否则它不是一个完整的测试用例。

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


【解决方案1】:

没有移动任何东西。

std::move 的名字真的很糟糕:它不会强制移动;它只是返回一个右值。由编译器决定调用std::vector&lt;int&gt; 的哪个构造函数,而决定了你是否得到了移动。

如果由于目标的移动构造函数不匹配而无法移动容器,则将通过基本重载规则使用复制构造函数。

#include <iostream>

struct T
{
    T() = default;
    T(const T&) { std::cout << "copy ctor\n"; }
    T(T&&)      { std::cout << "move ctor\n"; }
};

int main()
{
    T a;
    T b = std::move(a);   // "move ctor"

    const T c;
    T d = std::move(c);   // "copy ctor" - `const T&&` only matches copy ctor



    // (shut up GCC)
    (void) b;
    (void) d;
}

(live demo)

它是这样设计的(const T&amp;&amp; 能够绑定到 const T&amp;)至少部分是因为移动是尽力而为,正是为了让您不必在这种情况下与编译器错误作斗争。

【讨论】:

  • 他还可以通过将向量包装到另一个名为 MyVector 的类中来禁用复制,例如实现 vector 定义的相同构造函数,将 operator= 设为私有,然后尝试做同样的事情并得到一个编译错误。
  • @staticx:这太荒谬了。
  • 是的,但至少它会证明复制正在发生而不是移动,或者更确切地说是移动语义
  • Tnx 我明白了..我认为最好删除 const&& ctor .. T(const T&&)=delete;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-20
  • 1970-01-01
  • 2017-03-31
相关资源
最近更新 更多