考虑以下类。
struct with_copy {
with_copy() = default;
with_copy(with_copy const&) {}
with_copy& operator=(with_copy const&) { return *this; }
};
struct foo {
with_copy c;
std::unique_ptr<int> p;
};
with_copy
有复制构造函数吗?是的。它是明确定义的。with_copy
有移动构造函数吗?不会。显式复制构造函数会阻止生成它。- 是否
with_copy
有已删除的移动构造函数?不,没有移动构造函数与删除构造函数不同。已删除的移动构造函数将尝试移动格式错误而不是退化为副本。 - 可复制吗
with_copy
?是的。它的复制构造函数用于复制。 - 是
with_copy
可移动的吗?是的。它的复制构造函数用于移动。
...现在是棘手的。
foo
有复制构造函数吗?是的。它有一个已删除的,因为由于调用unique_ptr
的已删除复制构造函数,它的默认定义格式不正确。foo
有移动构造函数吗?GCC 说是,clang 说不。- 是否
foo
有已删除的移动构造函数?GCC 和 clang 都说不。 - 可复制吗
foo
?不,它的复制构造函数被删除了。 - 是
foo
可移动的吗?GCC 说是,clang 说不。
(当考虑分配而不是构造时,行为是相似的。)
据我所知,GCC 是正确的。foo
应该有一个移动构造函数,对每个成员执行移动,在这种with_copy
情况下会退化为副本。Clang 的行为似乎很荒谬:我有一个有两个可移动成员的聚合体,但我的聚合体是一块不可移动的砖。
谁是对的?