【发布时间】:2014-01-03 17:03:04
【问题描述】:
考虑以下类。
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 的行为似乎很荒谬:我有一个包含两个可移动成员的聚合体,但我的聚合体是一块不可移动的砖。
谁是对的?
【问题讨论】:
-
从技术上讲,我认为 Standardese 是
with_copy复制构造函数是用户提供的 -
在 n3485 中,[class.copy]/11 说如果“对于移动构造函数,非静态数据成员或直接或虚拟基类的类型不具有一个移动构造函数,不能轻易复制。”而且
with_copy是不可轻易复制的。 -
@DyP 没有编译器生成删除的移动构造函数:S(而且这些规则很荒谬)
-
因为未声明隐式删除的移动构造函数,/9.
-
顺便说一句,这在 C++1y 中发生了变化。据我所知,github repo 中的最新草案说
foo有一个移动构造函数。
标签: c++ c++11 user-defined-functions move-semantics implicit-declaration