c++ - 为什么我们可以在 `std::move` 对象上使用 `const`?

标签 c++ c++11

在 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/

相关文章:

c++ - 有理由不使用固定宽度类型吗?

c++ - 如何通过聚合初始化来初始化自定义数组类?

c++ - 将浮点值的 std::vector 传递给函数会稍微改变值

c++ - 如何调整我的功能模板,使它们可以是 "partially specialized"?

c++ - GPUTimer 作为一个单独的类

c++ - 如果 'foo' 是引用变量, [&foo]{ ... } 捕获和 [foo]{ ... } 捕获之间有区别吗?

c++ - TCS MockVita 2019 第二轮问题 : Hop Game

c++ - 如何使用ffmpeg实现像get_next_frame一样的功能?

c++ - C++ 11中与std::atomic的同步

c++ - std future 异常 - 已检索,std bug?