我有一个简单的代码:
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对象那么该代码是如何编译的?!
答案 0 :(得分:9)
你不移动任何东西。
std::move
的命名非常糟糕:它不会强制移动;它只返回一个右值。由编译器来决定调用std::vector<int>
的哪个构造函数,以及 决定是否进行移动的
如果由于目标的移动构造函数不匹配而无法移动容器,则将通过基本重载规则使用复制构造函数。
#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;
}
它的设计方式(const T&&
能够绑定到const T&
)至少部分是因为移动旨在尽力而为,完全是为了让你不在这种情况下,em>必须与编译错误作斗争。