最近,我遇到了这个答案,它描述了如何初始化std::array
非默认可构造元素。我并不感到惊讶,因为这个答案显然没有做任何默认构造。
相反,它std::array
使用聚合初始化构造一个临时变量,然后在函数返回时移动(如果移动构造函数可用)或复制到命名变量中。所以我们只需要移动构造函数或复制构造函数可用。
或者我是这么想的……
然后是这段让我感到困惑的代码:
struct foo {
int x;
foo(int x) : x(x) {}
foo() = delete;
foo(const foo&) = delete;
foo& operator=(const foo&) = delete;
foo(foo&&) = delete;
foo& operator=(foo&&) = delete;
};
foo make_foo(int x) {
return foo(x);
}
int main() {
foo f = make_foo(1);
foo g(make_foo(2));
}
所有五个特殊成员构造函数/运算符都被显式删除,所以现在我应该不能从返回值构造我的对象,对吗?
错误的。
令我惊讶的是,它在 gcc 中编译(使用 C++17)!
为什么会这样编译?foo
显然,要从函数中返回 a make_foo()
,我们必须构造 a foo
。这意味着在main()
函数中,我们foo
从返回的 中分配或构造 a foo
。这怎么可能?!