当且仅当我删除Foo的自定义析构函数时,以下代码才会编译.
struct Foo {
std::unique_ptr <int> bar;
~Foo (void) {} // This Line
};
std::vector <Foo> foos;
foos.push_back (Foo ());
Run Code Online (Sandbox Code Playgroud)
以下是我认为我对这种情况的理解:
它失败,因为unique_ptrs无法复制,并std::vector::push_back (thing)调用thing's复制构造函数.如果我编写Foo一个明确移动的自定义复制构造函数bar,那么一切都会好的.
但是,禁用This Line将导致代码编译.
我想,这应该无法编译,即使没有This Line,因为我仍然在尝试push_back一个unique_ptr.
为什么没有自定义析构函数就能成功,为什么添加自定义析构函数会导致它失败?
编辑:gcc -std=gnu++11在Debian Linux 64位上使用
根据标准"12.8.9复制和移动类对象[class.copy]"
如果类X的定义没有显式声明移动构造函数,那么当且仅当以下情况时,将隐式声明一个默认值:
- X没有用户声明的复制构造函数,
- X没有用户声明的复制赋值运算符,
- X没有用户声明的移动赋值运算符,
- X没有用户声明的析构函数,和
- 移动构造函数不会被隐式定义为已删除.
因此,如果一个类没有用户定义的析构函数,那么将声明一个move-constructor.根据标准的"12.8.15",这将为unique_ptr类成员调用move-constructor :
非联合类X的隐式定义的复制/移动构造函数执行其基础和成员的成员复制/移动.
如果一个类具有用户定义的析构函数,则应该显式声明move-constructor:
struct Foo {
std::unique_ptr <int> bar;
Foo() = default;
Foo(Foo&&) = default;
~Foo (void) {} // This Line
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
817 次 |
| 最近记录: |