保留std :: initializer_list的副本是否安全?理由是什么?

Ad *_*d N 8 c++ initializer-list c++11 c++14

在我的环境中,它std::initializer_list被实现为指向第一个元素的指针和一个大小.仍然在我的具体设置中,我能够观察到:

  • 基础数据在当前函数框架中分配(因为指向第一个元素的指针是这样说的)
  • initializer_list从函数返回by值不会更改指针的值(导致数据不会与initializer_list一起复制的结论).

如果副本可以比原始对象更长initializer_list,那么复制一个是不安全的.

  • 是否会通过进一步发布C++标准来维护这种行为?
  • 同样重要的是,这种行为背后的理由是什么?(今天我觉得很难,所以我天真地说它违背了"最不惊讶"这个心爱的原则)

Dan*_*lKO 9

从C++ 11标准,18.9 [support.initlist]:

2类型为initializer_list的对象提供对const E类型对象数组的访问.[注意:一对指针或指针加上一个长度将是initializer_list的明显表示.initializer_list用于实现8.5.4中指定的初始化列表.复制初始化列表不会复制基础元素. - 结束说明]

这就像是指向对象.您还可以使指针比对象更活跃.如果你想"安全地"做,请改为/存储元素向量.

复制元素会使它变得昂贵,因此没有人会使用它.可用文档清楚地说明了它的作用.

编辑:

这是Stroustrup的建议initializer_list:N2100.阅读它可能会启发它的设计决策.

  • 从c ++ 14开始,我们对其生命周期有更强的保证,比如你的链接:你的答案应该反映出来 (2认同)
  • 因为传递指针+大小非常快.你应该在函数参数中使用它,而不是用于存储.要存储元素,您将使用`vector <T>`,而语法几乎没有变化. (2认同)
  • 实际上,它们可能使它不可复制,所以你只能通过`const initializer_list <T>&`来使用它.Stroustrup争辩说,由于它是一个小对象,通过复制传递它简化了`.begin()`,`.ndnd()`的内联和`.size()`的`constexpr`评估:http:// www .开-std.org/JTC1/SC22/WG21 /文档/文件/ 2006/n2100.pdf (2认同)