为什么c++ 11的移动操作符(=)的行为不同?
Why is the C++11 move operator (=) behavior different
我已经在c++ 11中测试了move Semantic。我写了一个带有move构造函数的类。
class DefaultConstructor
{
public:
DefaultConstructor(std::vector<int> test) :
m_vec(std::forward<std::vector<int>>(test))
{
};
DefaultConstructor(DefaultConstructor &&def) :
m_vec(std::forward<std::vector<int>>(def.m_vec))
{
}
DefaultConstructor& operator=(DefaultConstructor&& def) {
m_vec = std::move(def.m_vec);
return *this;
}
DefaultConstructor& operator=(const DefaultConstructor&) = delete;
DefaultConstructor(DefaultConstructor &) = delete;
std::vector<int> m_vec;
};
我写了一个使用move语义的main函数。我理解在移动语义中发生了什么,它是一个伟大的工具。但有些行为我无法解释。当我调用主函数DefaultConstructor testConstructor2 = std::move(testConstructor);
时,DefaultConstructor& operator=(DefaultConstructor&& def)
应该被调用。但是Visual Studio 2015调用move构造函数。
int main()
{
std::vector<int> test = { 1, 2, 3, 4, 5 };
DefaultConstructor testConstructor(std::move(test));
DefaultConstructor testConstructor2 = std::move(testConstructor);
DefaultConstructor &testConstructor3 = DefaultConstructor({ 6, 7, 8, 9 });
DefaultConstructor testConstructor4 = std::move(testConstructor3);
swapMove(testConstructor, testConstructor2);
}
好吧,我想也许= Move运算符不再是必要的了。但我尝试了SwapMove功能。这个函数调用= move操作符。
template<typename T>
void swapMove(T &a, T &b)
{
T tmp(std::move(a));
a = std::move(b);
b = std::move(tmp);
}
有人能解释一下这两个呼叫的区别吗?a = std::move(b);
和DefaultConstructor testConstructor2 = std::move(testConstructor);
的调用不应该有相同的行为吗?
语法
DefaultConstructor testConstructor2 = something;
总是调用构造函数,因为对象testConstructor2
还不存在。Operator =只能在已经构造的对象上下文中调用
This:
T foo = bar;
称为复制初始化。它通常(但不总是)等同于:
T foo(bar);
的区别在于,后者是对T
的构造函数的直接函数调用,而前者试图构造一个从decltype(bar)
到T
的隐式转换序列。因此,存在直接初始化成功而复制初始化失败的情况。不管怎样,初始化就是初始化:它是构造函数调用,而不是赋值调用。
在我们的例子中,这两行是完全等价的:
DefaultConstructor testConstructor2 = std::move(testConstructor);
DefaultConstructor testConstructor2{std::move(testConstructor)};
它们都不调用DefaultConstructor::operator=
DefaultConstructor testConstructor2 = std::move(testConstructor);
是构造,不是赋值。这完全类似于c++ 11之前的相同类型代码中的复制构造与赋值。
- 将对象移动到std::shared_ptr
- 何时在引用或唯一指针上使用移动语义
- 如何从具有移动语义的类对象中生成共享指针
- 将shared_ptr移动到<StructA>shared_ptr<变体<结构A、结构 B>>
- C / C++ 移位/偏移/向左或向右移动位图?
- MSVC将仅移动结构参数解释为指针
- 自定义先决条件对移动分配运算符有效吗
- 返回值优化:显式移动还是隐式
- 当有分配器意识的容器被复制/移动时,反弹分配器是否被复制/移走
- 为什么复制而不是移动数据元素?
- 可以使用移动语义更改或改进此C++代码吗?
- 使lambda不可复制/不可移动
- c++在使用指针时移动语义
- 将QGraphicsItem的移动区域限制在多边形区域内
- SendInput()鼠标移动计算
- 按值 C++ 返回时进行双倍移动
- 移动二维数组中的字符
- 为什么不调用移动构造函数?(默认情况下只有构造器,没有别的)
- 安全到标准:移动会员?
- OpenVR:向视图方向移动