【问题标题】:Why isn't `std::initializer_list` defined as a literal type?为什么不将 `std::initializer_list` 定义为文字类型?
【发布时间】:2015-02-14 06:07:08
【问题描述】:

这是这个问题的后续:Is it legal to declare a constexpr initializer_list object?

自 C++14 起,std::initializer_list 类的所有方法都标有constexpr。能够通过执行来初始化实例似乎很自然 constexpr std::initializer_list<int> list = {1, 2, 3}; 但是 Clang 3.5 抱怨 list 没有被常量表达式初始化。 As dyp pointed out in a comment,任何要求 std::initializer_list 为文字类型的要求似乎都已从规范中消失。

如果我们甚至不能这样初始化一个类,那么将它完全定义为 constexpr 有什么意义呢?这是标准中的疏忽吗?将来会修复吗?

【问题讨论】:

  • Richard Smith 似乎暗示 here std::initializer_list 已成为文字类型。但是,我在标准中找不到这样的要求。第二个问题是“可以将 constexpr 非静态成员函数声明为非文字类型的成员吗?”,参见 CWG DR 1684
  • 这很奇怪,当你把它放在全局范围内时,clang++ 会编译它:coliru.stacked-crooked.com/a/dab2834181fb8ea4(这是clang bug 15117)对我来说闻起来像另一个编译器错误。
  • “这是标准中的疏忽,将来会得到修复吗?” - 一般而言,C++14 是正确的。
  • 仅作记录:GCC 4.9.1 对此没问题。

标签: c++ language-lawyer c++14 initializer-list constexpr


【解决方案1】:

标准委员会似乎打算将initializer_list 用作文字类型。但是,它看起来并不是一个明确的要求,而且似乎是标准中的一个错误。

从第 3.9.10.5 节开始:

一个类型是一个文字类型,如果它是:
- 具有以下所有属性的类类型(第 9 条):
- - 它有一个微不足道的析构函数,
- - 它是一个聚合类型 (8.5.1) 或至少有一个 constexpr 构造函数或构造函数模板不是复制或移动构造函数,并且
- - 它的所有非静态数据成员和基类都是非易失文字类型。

从第 18.9.1 节开始:

namespace std {
  template<class E> class initializer_list {
  public:
    /* code removed */
    constexpr initializer_list() noexcept;
    // No destructor given, so trivial
    /* code removed */
  };
}

这满足第一个和第二个要求。

对于第三个要求:

来自第 18.9.2 节(强调我的):

initializer_list&lt;E&gt; 类型的对象提供对const E 类型对象数组的访问。 [注意:一对指针或一个指针加上一个长度将是initializer_list 的明显表示。 initializer_list 用于实现 8.5.4 中指定的初始化列表。复制初始值设定项列表不会复制底层元素。
——尾注]

因此,initializer_list 的实现的私有成员不需要是非易失文字类型;然而,因为他们提到他们相信一对指针或一个指针和一个长度将是“明显的表示”,他们可能没有考虑到有人可能会在 initializer_list 的成员中放入非文字的东西。

我会说这可能是 clang 和标准中的一个错误。

【讨论】:

    【解决方案2】:

    我记得在 C++11 发布后不久,我创建了一个 initializer_list,它的各个成员分配了动态内存,因此它们具有非平凡的 d'tor,因此 initializer_list 具有非平凡的 d'tor。在某些情况下,我想我在 initializer_list 部分构建时抛出了,其中构建的部分没有被破坏,导致内存泄漏。我确定编译器现在已经修复了。

    【讨论】:

      猜你喜欢
      • 2012-11-16
      • 1970-01-01
      • 2012-07-09
      • 2013-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-17
      相关资源
      最近更新 更多