【问题标题】:Why does the C++ standard library always pass std::initializer_list<T> by value rather than by reference?为什么 C++ 标准库总是按值而不是按引用传递 std::initializer_list<T>?
【发布时间】:2020-08-03 17:07:28
【问题描述】:

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

sizeof(T) &lt;= sizeof(void*) 时按值传递参数T就地构建并移入

但是,C++ 标准库似乎不符合规则。对于examplesizeof(std::initializer_list&lt;T&gt;) 大于sizeof(void*),但std::vector 有一个构造函数:

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

为什么 C++ 标准库总是传递 std::initializer_list&lt;T&gt; 按值而不是按引用?

【问题讨论】:

  • initializer_list 不是容器,旨在按值传递。现在很多人认为这是一个错误
  • @MM 有趣。你能指点我们讨论一下吗?
  • initializer_list 始终被设计为数组而不是容器的“轻量级包装器”(如果我没记错的话)。这通常意味着复制的开销——包括按值传递——是可以接受的低。这可以解释为什么标准库通过值而不是引用来传递它们。至于这被认为是一个错误 - 我会对此进行讨论。
  • 我不确定我是否理解这个问题。您的问题似乎是“我有这个规则,而 C++ 标准库不遵循这个规则。为什么不呢?”标准库是否需要有理由不遵循您的规则?此外,标准库还有许多其他地方不遵循您的规则(例如,每个采用谓词或其他可调用对象的算法都按值这样做)。

标签: c++ c++11 pass-by-reference standards pass-by-value


【解决方案1】:

由于在初始化范围内,已知值将被用作(即复制)容器的属性(例如向量、地图...),因此通过引用传递它们并没有性能提升。

【讨论】:

    【解决方案2】:

    来自initializer_list上的cppreference:

    底层数组的生命周期与任何其他临时对象相同,只是从数组初始化一个 initializer_list 对象可以延长数组的生命周期,就像将引用绑定到临时对象一样(有相同的例外,例如 for初始化一个非静态类成员)。

    所以initializer_list 已经像一个临时的引用。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-23
      • 2014-11-19
      • 2015-03-24
      • 2019-05-25
      • 1970-01-01
      • 2018-01-26
      • 1970-01-01
      • 2011-02-04
      相关资源
      最近更新 更多