80

在我在 SO 上看到的几乎每一篇涉及 a 的帖子中std::initializer_list,人们都倾向于std::initializer_list按值传递 a。根据这篇文章:

https://web.archive.org/web/20120707045924/cpp-next.com/archive/2009/08/want-speed-pass-by-value/

如果要复制传递的对象,则应按值传递。但是复制 astd::initializer_list不是一个好主意,因为

复制 astd::initializer_list不会复制底层对象。在原始初始化列表对象的生命周期结束后,不能保证底层数组存在。

那么为什么它的一个实例通常是按值传递而不是通过,例如const&,保证不会产生不必要的副本?

4

2 回答 2

70

它是按价值传递的,因为它很便宜。std::initializer_list,作为一个瘦包装器,最有可能实现为一对指针,因此复制(几乎)与通过引用传递一样便宜。此外,我们实际上并没有执行复制,我们(通常)执行移动,因为在大多数情况下,参数无论如何都是由临时构造的。然而,这不会对性能产生影响——移动两个指针与复制它们一样昂贵。

另一方面,访问副本的元素可能会更快,因为我们避免了额外的取消引用(引用的取消引用)。

于 2013-07-23T07:05:39.603 回答
15

可能出于同样的原因,迭代器几乎总是按值传递:复制迭代器被认为是“便宜的”。就initializer_list. 最后,像迭代器一样,被调用函数可能想要修改值,这意味着如果它通过对 const 的引用传递,它必须在本地复制它。

编辑:

只是概括一下:标准库通常假设最好按值传递迭代器、initializer_lists 和函数对象。因此,您应该确保您设计的任何迭代器、iterator_lists 或功能对象复制起来都很便宜,并且您应该在自己的代码中假设它们复制起来很便宜。关于何时使用对 const 的引用以及何时使用 value 的传统规则可能应该修改以反映这一点:

对于迭代器、initializer_lists 或函数对象以外的类类型,使用对 const 的引用传递;否则使用按值传递。

于 2013-07-23T08:09:07.590 回答