0

鉴于:

//C++17
#include <string>
struct Foo {
    int i;
    std::string str;
};

int main() {
    Foo foo{1, std::string("Hello, world!")};
}

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

如果不能,需要多少份?

4

1 回答 1

4

聚合初始化基本上执行逐元素复制初始化。所以这:

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
}
于 2017-12-17T15:08:42.263 回答