为什么C++标准库总是按值而不是引用传递 std::initializer_list<T>?

Why does the C++ standard library always pass std::initializer_list<T> by value rather than by reference?

提问人:xmllmx 提问时间:4/21/2020 最后编辑:xmllmx 更新时间:4/21/2020 访问量:102

问:

作为一名C++程序员,我被教导了传递参数的简单规则:

当或用于就地构建和移入时按值传递参数。Tsizeof(T) <= sizeof(void*)

但是,C++ 标准库似乎不符合该规则。例如,大于 ,但具有构造函数:sizeof(std::initializer_list<T>)sizeof(void*)std::vector

vector(std::initializer_list<T>, const Allocator&);

为什么 C++ 标准库总是按值传递而不是按引用传递?std::initializer_list<T>

C++ C++11 按引用传递 标准 按值传递

评论

2赞 M.M 4/21/2020
initializer_list不是容器,而是设计为按值传递。现在很多人认为这是一个错误
3赞 Peter - Reinstate Monica 4/21/2020
@M.M:有趣。你能给我们指出一个讨论吗?
2赞 Peter 4/21/2020
initializer_list总是被设计为数组的“轻量级包装器”(如果我没记错的话),而不是容器。这通常意味着复制的开销(包括按值传递)是可以接受的低。这可以解释为什么标准库通过值而不是引用来传递它们。至于这被认为是一个错误 - 我对这个问题的讨论很感兴趣。
1赞 Nicol Bolas 4/21/2020
我不确定我是否理解这个问题。你的问题似乎是“我有这个规则,而 C++ 标准库不遵循这个规则。为什么不呢?标准库是否需要有理由不遵循您的规则?此外,在许多其他地方,标准库不遵循您的规则(例如,每个采用谓词或其他可调用对象的算法都是按值执行的)。

答:

2赞 Jean-Marc Volle 4/21/2020 #1

由于在初始化范围内已知值将用作(即复制)作为容器的属性(例如向量,map,...),因此通过引用传递它们不会提高性能。

2赞 Alex Guteniev 4/21/2020 #2

cppreference on initializer_list

基础数组的生存期与任何其他临时对象相同,只是从数组初始化initializer_list对象会延长数组的生存期,就像将引用绑定到临时对象一样(但有相同的例外,例如初始化非静态类成员)。

所以已经像是对临时的引用。initializer_list

其背后的想法是将数据从临时存储器中移动或将其从只读内存直接复制到目标容器。它本身不是一个容器。initializer_list