在 C++11 中,我们可以编写如下代码:
struct Cat {
Cat(){}
};
const Cat cat;
std::move(cat); //this is valid in C++11
当我调用std::move
时,表示我要移动对象,即我要改变对象。移动一个 const
对象是不合理的,那么为什么 std::move
不限制这种行为呢?以后会是个陷阱吧?
这里的陷阱意味着布兰登在评论中提到:
" I think he means it "traps" him sneaky sneaky because if he doesn't realize, he ends up with a copy which is not what he intended."
在 Scott Meyers 的《Effective Modern C++》一书中,他举了一个例子:
class Annotation {
public:
explicit Annotation(const std::string text)
: value(std::move(text)) //here we want to call string(string&&),
//but because text is const,
//the return type of std::move(text) is const std::string&&
//so we actually called string(const string&)
//it is a bug which is very hard to find out
private:
std::string value;
};
如果 std::move
被禁止对 const
对象进行操作,我们很容易找出错误,对吧?
最佳答案
你忽略了一个技巧,即 std::move(cat)
实际上并没有移动任何东西。它只是告诉编译器 try 移动。但是,由于您的类没有接受 const CAT&&
的构造函数,它将改为使用隐式 const CAT&
复制构造函数,并安全地复制。没有危险,没有陷阱。如果复制构造函数因任何原因被禁用,您将收到编译器错误。
struct CAT
{
CAT(){}
CAT(const CAT&) {std::cout << "COPY";}
CAT(CAT&&) {std::cout << "MOVE";}
};
int main() {
const CAT cat;
CAT cat2 = std::move(cat);
}
打印COPY
,而不是MOVE
。
http://coliru.stacked-crooked.com/a/0dff72133dbf9d1f
请注意,您提到的代码中的错误是性能问题,而不是稳定性问题,因此此类错误永远不会导致崩溃。它只会使用较慢的拷贝。此外,没有移动构造函数的非常量对象也会出现这样的错误,因此仅添加 const
重载不会捕获所有这些。我们可以检查从参数类型移动构造或移动赋值的能力,但这会干扰假定依赖复制构造函数的通用模板代码。
哎呀,也许有人希望能够从 const CAT&&
构造,我能说他不能呢?
关于c++ - 为什么我们可以在 `std::move` 对象上使用 `const`?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28595117/