【问题标题】:When is the move constructor called in the `std::move()` function?什么时候在 `std::move()` 函数中调用移动构造函数?
【发布时间】:2013-01-22 20:41:42
【问题描述】:

函数std::move()定义为

template<typename T>
typename std::remove_reference<T>::type&& move(T && t)
{ 
    return static_cast<typename std::remove_reference<T>::type&&>( t ); 
}

我可以想象要调用移动构造函数的四个地方:

  1. 参数传递时。
  2. 执行转换时。
  3. 返回结果时。
  4. 不在std::move() 函数本身,但可能在返回的引用最终到达的地方。

我会赌 4 号,但我不能 100% 确定,所以请解释一下你的答案。

【问题讨论】:

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


    【解决方案1】:

    没有进行移动构建。 std::move() 接受引用并返回引用。 std::move() 基本上只是一个演员表。

    您的猜测 4. 是正确的(假设您实际上最终调用了移动构造函数)。

    【讨论】:

    • std::move 是一个非常愚蠢的名字,因为它不会移动任何东西(也就是说,是的,答案是4)。我与委员会成员有过争论,他们认为这很好,因为“人们只会使用std::move 作为移动某物的前兆”。我觉得这完全违背了C++的精神
    • @LightnessRacesinOrbit 是的,我也觉得 move 这个名字很混乱。
    • 它应该被称为to_movablemake_movable。我想这对于使用没有自动完成功能的 IDE 的人来说有点太多了。
    • @Ali 有趣的历史课。尽管如此,make_movable 与那篇文章的主要观点是一致的(并且不像move 那样完全错误。不可否认,它是错误的。它没有描述该方法的作用。它描述了它没有 做。)。
    【解决方案2】:

    std::move 只是一个类型转换,它告诉编译器该类型是一个右值。

    【讨论】:

    • 我就是这么想的。因此std::move() 实际上并没有移动,甚至不需要导致移动操作。
    • 这就是为什么我不明白有些人说此举可以防止 (N)RVO。根据我对 GCC 的实验,(N)RVO 与 move 配合得很好。
    • 使用return std::move(local_var); 而不仅仅是return local_var; 确实会抑制(N)RVO,请参阅this
    • 它确实抑制了 (N)RVO,只是因为标准规定 在您编写 return local_var; 时允许发生 (N)RVO。
    • @ArtemGr 尝试使用更符合要求的版本stacked-crooked.com/view?id=d4bb782e20433f48f9a61cc2106d502d
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-13
    • 2015-02-14
    • 2021-12-12
    • 1970-01-01
    • 2015-03-21
    • 2023-03-16
    • 2013-12-08
    相关资源
    最近更新 更多