繁体   English   中英

为什么不将 `std::initializer_list` 定义为文字类型?

[英]Why isn't `std::initializer_list` defined as a literal type?

这是这个问题的后续: 声明 constexpr initializer_list 对象是否合法? .

从 C++14 开始, std::initializer_list类的所有方法都标有constexpr 能够通过执行constexpr std::initializer_list<int> list = {1, 2, 3};来初始化实例似乎很自然constexpr std::initializer_list<int> list = {1, 2, 3}; 但是 Clang 3.5 抱怨list没有被常量表达式初始化。 正如 dyp 在评论中指出的那样,std::initializer_list是文字类型的任何要求似乎都从规范中消失了。

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

标准委员会似乎打算将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<E>的对象提供对类型为const E的对象数组的访问。 [注意:一对指针或一个指针加上一个长度将是initializer_list明显表示。 initializer_list用于实现 8.5.4 中指定的初始化列表。 复制初始化列表不会复制底层元素。
——尾注]

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

我想说这可能是 clang 和标准中的错误。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM