Kno*_*abe 2 c++ unique-ptr move-constructor c++11
如果我使用a unique_ptr<T>来构建一个pimpl类,我理解调用T析构函数的编译器生成的函数需要T是一个完整的类型.但是pimpl类的移动构造函数呢?编译器生成的版本只调用了unique_ptr移动构造函数.该功能不会破坏任何东西.此外,pimpl类生成的移动构造函数是隐式的noexcept,因此它的主体不可能抛出异常,导致它必须退出并销毁unique_ptr子对象.
看起来好像下面的代码应该编译:
#include <memory>
class Widget { // has implicit move ctor
struct Impl;
std::unique_ptr<Impl> pImpl;
};
int main()
{
Widget *pw1 = nullptr;
new Widget(std::move(*pw1)); // call move ctor. Rejected by
} // gcc, clang, and MSVC
Run Code Online (Sandbox Code Playgroud)
正如评论所说,这个代码被所有gcc,clang和MSVC拒绝.每个人抱怨对不完整类型的操作无效.这是标准要求的吗?如果是这样,那是哪一部分
请注意,此处的问题是编译,因此上述代码由于取消引用空pw1指针而未定义的运行时行为无关紧要.出于同样的原因,new在最后一个语句中调用引起的内存泄漏并不重要.
很近.
此外,pimpl类生成的移动构造函数是隐式的
noexcept,因此它的主体不可能抛出异常,导致它必须退出并销毁unique_ptr子对象.
在非委托构造函数中,可能会调用每个可能构造的类类型子对象的析构函数(12.4).[ 注意:此规定确保在抛出异常时可以为完全构造的子对象调用析构函数(15.2).- 结束说明 ]
这是一个odr-use([basic.def.odr]/3),因此会导致unique_ptr析构函数的隐式实例化,而析构函数最终需要一个完整的类型.
noexcept构造函数没有特殊情况.