我一直认为std::initializer_list
是一个轻量级的代理对象,它将仅从列表项中获取const引用,而不是复制它们。
但是后来我发现实际上是在这种情况下执行复制:
struct Test {
Test() {
std::cout << this << " default ctor" << std::endl;
}
Test(const Test&) {
std::cout << this << " copy ctor" << std::endl;
}
~Test() {
std::cout << this << " destructor" << std::endl;
}
};
int main() {
Test a;
Test b;
Test c;
std::cout << "for begin" << std::endl;
for(const auto& current : {a, b, c}) {
std::cout << "Current: " << ¤t << std::endl;
}
std::cout << "for end" << std::endl;
}
以上代码的输出:
0x63e5acda default ctor
0x63e5acdb default ctor
0x63e5acdc default ctor
for begin
0x63e5acdd copy ctor
0x63e5acde copy ctor
0x63e5acdf copy ctor
Current: 0x63e5acdd
Current: 0x63e5acde
Current: 0x63e5acdf
0x63e5acdf destructor
0x63e5acde destructor
0x63e5acdd destructor
for end
0x63e5acdc destructor
0x63e5acdb destructor
0x63e5acda destructor
在这种情况下,为什么std :: initializer_list会复制项目,而不仅仅是获取它们的引用?是否有任何“优雅”的方式来编写类似于for(auto&& x : {a, b, c})
的东西,但不复制现有项目?
答案 0 :(得分:4)
摘自std::initializer_list
上的文档:
基础数组是类型为const T [N]的临时数组,其中每个元素都是从初始初始值设定项列表的相应元素进行复制初始化的(除非缩小转换无效)。 。基础数组的生存期与任何其他临时对象相同,不同之处在于,从数组初始化initializer_list对象可以延长数组的生存期,就像将引用绑定到临时对象一样(但有相同的例外,例如用于初始化非临时对象)。 -static类成员)。基础数组可以分配在只读内存中。