编译器在VC12 (VS2013)中生成移动构造函数行为
Compiler generated move constructor behavior in VC12 (VS2013)
我试图测试编译器生成的移动构造函数的行为为一个类的数据成员为"std::string"answers"std::shared_ptr"。
class Record
{
public:
Record():mData("defRec"), mDataPtr(new std::string("defRec"))
{}
Record(const std::string &str): mData(str), mDataPtr(new std::string(str))
{}
private:
std::string mData;
std::shared_ptr<std::string> mDataPtr;
};
任何D'tor、move和copy操作都被故意省略,以允许编译器生成move操作。类数据成员被特别选择,因为与Record类不同,它们都定义了D'tor、移动和复制操作。
在以下代码之后,
Record rec1(std::string("Record1"));
Record rec2(std::move(rec1));
检查对象rec1(通过调试器或通过定义访问方法),mData仍然包含"Record1"和mDataPtr仍然持有字符串指针。
但是,如果我提供自己的Move构造函数,如下所示
Record(Record&& rhs) : mData(std::move(rhs.mData)), mDataPtr(std::move(rhs.mDataPtr))
{}
然后在以下代码
之后Record rec1(std::string("Record1"));
Record rec2(std::move(rec1));
检查对象rec1时,mData和mDataPtr都变为空对象。
我不明白为什么编译器生成的移动构造函数为"类记录"给出了不同的结果,我的版本移动构造函数为"类记录",我只是确保移动C'tor的数据成员被调用。我期望相同的行为编译器生成移动构造函数?
虽然被移动的from对象应该处于有效状态,但数据成员的move构造函数(在这两种情况下都没有定义)给出了不同的结果。
这是VC12 (VS2013)的已知限制吗?
是的,这是该编译器的已知限制。move构造函数可以是隐式的吗?问题的EDIT EDIT
告诉我们:
我联系了Stephan T Lavavej,问他为什么VC 2012没有似乎遵循草案12.8关于含蓄行动的规定构造函数生成。他好心地解释了:这更像是一个"尚未实现的功能",而不是一个bug。VC目前实现了我所说的右值引用v2.0,其中移动因子/赋值永远不会隐式生成,也不会影响隐式生成复制因子/赋值。c++ 11指定了右值参考v3.0,这是您正在查看的规则。
简而言之,编译器永远不会生成move构造函数,即使在显式std::move
存在的情况下,也会调用copy构造函数。
根据标准,有很多原因不需要编译器生成默认的move构造函数,但是你的类似乎没有违反任何一个。
- 为什么不调用移动构造函数?(默认情况下只有构造器,没有别的)
- std::vector::p ush_back() 不会在 MSVC 上编译具有已删除移动构造函数的对象
- 仅包含可移动 std::map 的类的移动构造函数不起作用
- 为什么调用复制构造函数而不是移动构造函数?
- 基类中的默认析构函数禁用子类中的移动构造函数(如果有成员)
- 从具有按值捕获的 lambda 移动构造 std::函数时,移动构造函数调用两次
- 移动构造函数和右值引用
- 为什么 std::memmove 中联合的默认非平凡移动构造函数C++?
- 具有专用化的模板类中的可靠条件复制和移动构造函数
- C++:为什么不调用移动构造函数?
- 移动构造函数永远不会被调用
- C++:关于使用 Stroustrup 示例移动构造函数/赋值的问题
- 运算符+ 的规范实现涉及额外的移动构造函数
- C ++为什么在移动构造函数中需要移动/前进
- 为什么在删除"移动构造函数"时使用"复制构造函数"?
- 为什么这里不调用移动构造函数?
- 隐式移动构造函数
- 如何为具有私有成员的派生类实现移动构造函数
- 为什么不调用移动构造函数
- 是否可以避免在以下代码中复制/移动构造函数的需要?