c++ - 为什么必须复制 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'tors 不是候选对象。所以下面的代码格式不正确
#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 编译器下,由于您提供了一个纯右值(纯右值,而不是对象)的初始化程序,因此 C++ 的初始化规则要求直接初始化目标,而不创建中间对象。即使上下文被称为“复制初始化”,也没有多余的对象。
推荐阅读
- java - 没有html css标签java的Lucene索引
- python - 将具有任意维数的列表数据转换为多维列表
- java - 如何根据给定的间隔分隔pdf
- vba - 这个字符串中“#”的作用是什么?
- javascript - jquery tabledit 下拉菜单:是否可以从 mysql 数据库中检索值?
- reactjs - graphql 突变有效负载中缺少字段
- powershell - Get-Variable 如何去掉 DOT DOT DOT
- cocoa - pod setup --verbose 不做任何事情
- c++ - 对数组中的数字进行平方,找到总和和最大的数字
- java - 如何围绕具有相似行为的不相交类型设计代码?