rvalue引用没有std ::移动
Rvalue references without std::move
我有以下class
class widget {
// The methods only print their name, i.e. c'tor, destructor etc.
public:
widget();
widget(const widget&);
widget(widget&&);
~widget();
auto operator=(const widget&) -> widget&;
auto operator=(widget&&) -> widget&;
};
我在以下代码中使用的
#include "widget.h"
auto main() -> int {
widget c(std::move(widget()));
c = std::move(widget());
return 0;
};
最终的行为对我来说是可以理解的。在第一个呼叫中,构造了一个小部件,然后调用移动构造函数,并在临时小部件上调用破坏者。
第二个呼叫也相同,期望调用移动分配运算符,而不是移动构造函数。离开主要方法,在c
上调用了驱动器。
现在是有趣的部分:
#include "widget.h"
auto main() -> int {
widget c((widget()));
c = widget();
return 0;
};
如果我省略了std::move
的呼叫,则第一种情况会停止工作,并且仅导致一个构造函数调用。而第二种情况仍然像以前一样工作。
我在这里想念什么?为什么这两个函数调用对其参数的处理方式有所不同?我在GCC和Clang上尝试了一下。
widget()
是纯rvalue(prvalue),因此在行中
widget c((widget())); // use widget c{widget()} or c{widget{}} for more clear code
它将被移动。但是,编译器只是执行复制/移动省略。用-fno-elide-constructors
编译,您会看到对移动构造函数的所有荣耀的呼叫。
每当您明确使用std::move
移动Prvalue时,您都不允许编译器执行elision;这就是为什么您会在第一个片段中看到MOVE构造函数。这就是为什么尝试使用std::move
作为返回来"帮助"编译器几乎总是一个坏主意(除非您真的想返回rvalue参考)。
相关文章:
- 仅包含可移动 std::map 的类的移动构造函数不起作用
- 如何在窗口之间移动 std::unique_ptr 而不会冒内存泄漏的风险?
- 为什么移动 std::可选不重置状态
- C++:我可以重用/移动 std::list 元素从中间到结尾吗?
- 我应该移动 std::exchange ed 成员吗?
- 移动 std::bitset<N> 是否超过 N 个位置未定义的行为?
- 标准是否保证在移动std::p ackaged_task后安全使用std::future?
- 用于移动 std::shared_ptr 的函数声明
- 如何移动 std::ostringstream 的底层字符串对象?
- 移动std::shared_ptr会使程序崩溃
- c++11移动std::deque或std::list的插入
- 如何移动std::ostream
- 移动std::bind和std::thread中的语义/行为
- 为什么我不能移动 std::ofstream?
- 从char*中移动std::string的构造函数
- 移动 std::vector 成员的语义
- 移动std::unique_locks的std::矢量
- 复制/移动std::映射中键/值类型的要求
- 移动std::互斥锁的构造函数
- 在容器之间移动std::unique_ptr