[英]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.