可以在C 17中汇总初始化

Can copy elision be perfomed in aggregate initialization in c++17?

本文关键字:初始化      更新时间:2023-10-16

给定:

//C++17
#include <string>
struct Foo {
    int i;
    std::string str;
};
int main() {
    Foo foo{1, std::string("Hello, world!")};
}

Foo::iFoo::str可以直接从1std::string(...)初始初始化,而不是被复制到它们中,并解释为什么/不能/不能使用C 17标准(可能是用于测试目的的某些代码)?

如果不能,需要多少份?

汇总初始化基本上执行元素副本限制。因此:

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中有一个新规则,该规则说:

如果初始化器表达式是prvalue,并且源类型的CV UNCOLIFIED版本与目标类别相同,则使用初始化器表达式来初始化目标对象。 [示例: 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
}