为什么必须复制std::initializer_list的元素



cppreference说:

底层数组是const T[N]类型的临时数组,其中每个元素都被复制初始化(除了缩小转换无效(原始初始值设定项列表。基础数组的生存期是与任何其他临时对象相同,只是初始化数组中的initializer_list对象延长数组与将引用绑定到临时(具有相同异常,例如用于初始化非静态类成员(。这个底层阵列可以被分配在只读存储器中。

这个决定背后的原因是什么?为什么搬家不好?

复制省略怎么办?

struct A { A(const A&){ std::cout << "Oh no, a copy!n"; } };
struct B { B(std::initializer_list<A> il); };
int main()
{
B b{ A{} };
return 0;
}

我的编译器删掉了副本。但是这些副本一定会被删掉吗?

C++中的"复制初始化"并不意味着一定要复制。它只是将要进行初始化的约束的正式名称。例如,当复制初始化时,显式的c'TOR不是候选者。因此,以下代码将是格式错误的

#include <iostream>
#include <initializer_list>
struct A {
explicit A() = default;
A(const A&){ std::cout << "Oh no, a copy!n"; } 
};
struct B { B(std::initializer_list<A> il); };
int main()
{
B b{ {} };
return 0;
}

列表中的单个成员需要从{}进行复制初始化,这需要调用默认的c'tor。但是,由于c'tor标记为显式,因此无法进行此初始化。

复制省略在C++17之前当然是可能的,并且在某些上下文中,在C++17之后是强制性的。在您的示例中,在C++17编译器下,由于您提供的初始值设定项是prvalue(纯右值,而不是对象(,C++的初始化规则要求直接初始化目标,而不创建中间对象。即使上下文被称为"复制初始化",也没有多余的对象。

最新更新