这是对此问题的跟进: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,那么将一个类完全定义为constexpr的重点是什么?这是标准中的疏忽,将来会得到修复吗?
答案 0 :(得分:5)
标准委员会似乎打算将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
的成员中放入非文字的东西。
我说这可能是铿锵声和标准中的错误,可能。
答案 1 :(得分:0)
我记得在C ++ 11发布之后不久,我正在创建一个initializer_list,其单个成员分配了动态内存,因此它们具有非平凡的d'tor,因此,initializer_list具有非平凡的d'tor。在某些情况下,我认为我是在部分构造initializer_list时抛出的,其中所构造的部分没有被破坏,导致内存泄漏。我确定编译器已经修复。