聚合初始化基本上执行逐元素复制初始化。所以这:
struct Foo {
int i;
std::string str;
};
Foo foo{1, std::string("Hello, world!")};
执行与以下相同的初始化:
int i = 1;
std::string str = std::string("Hello, world!");
我们在 C++17 中有一条新规则:
如果初始化表达式是纯右值并且源类型的 cv 非限定版本与目标类是同一类,则初始化表达式用于初始化目标对象。[示例: T x = T(T(T()));
调用T
默认构造函数进行初始化x
。—结束示例]
这意味着第二次初始化必须表现得像你写的那样:
std::string str("Hello, world!");
也就是说,零拷贝。
新规则的一个很好的演示是以下示例:
struct X {
X(int ) { }
X(X&& ) = delete;
};
struct Y {
X x;
};
int main() {
Y y{X{4}}; // ill-formed in C++14 due to deleted move ctor
// ok in C++17, no move required
}