为什么不将`std :: initializer_list`定义为文字类型? [英] Why isn't `std::initializer_list` defined as a literal type?

查看:175
本文介绍了为什么不将`std :: initializer_list`定义为文字类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是此问题的后续:

This is a follow-up of this question: Is it legal to declare a constexpr initializer_list object?.

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

Since C++14, the std::initializer_list class has all of its methods marked with constexpr. It seems natural to be able to initialize an instance by doing constexpr std::initializer_list<int> list = {1, 2, 3}; but Clang 3.5 complains about list not being initialized by a constant expression. As dyp pointed out in a comment, any requirement for std::initializer_list to be a literal type seem to have vanished from the specs.

如果我们甚至不能初始化这个类,那么有一个类完全定义为constexpr的意义是什么?

What's the point of having a class fully defined as constexpr if we can't even initialize it as such? Is it an oversight in the standard and will get fixed in the future?

推荐答案

标准委员会似乎打算在 initializer_list 是一个文字类型。

The standard committee seems to intend on initializer_list being a literal type. However, it doesn't look like it's an explicit requirement, and seems to be a bug in the standard.

从§3.9.10.5开始:

From § 3.9.10.5:


如果是类型,则为类型:

- 类类型(第9条)所有以下属性:

- - 它有一个简单的析构函数,

- - 它是一个聚合类型(8.5.1)或至少有一个constexpr
不是复制或移动构造函数的构造函数或构造函数模板,并且

- - 其所有非静态数据成员和基类都是非易失性文字类型。

A type is a literal type if it is:
- a class type (Clause 9) that has all of the following properties:
- - it has a trivial destructor,
- - it is an aggregate type (8.5.1) or has at least one constexpr constructor or constructor template that is not a copy or move constructor, and
- - all of its non-static data members and base classes are of non-volatile literal types.

从第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 */
  };
}

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

This satisfies the first and second requirements.

对于第三个要求:

从§18.9.2(强调我):

From § 18.9.2 (emphasis mine):


类型 initializer_list 的对象提供对类型 const E 的对象数组的访问, code>。 [注意:一对指针或指针加上长度将是 initializer_list 的明显表示。 initializer_list 用于实现8.5.4中指定的初始化器列表。复制初始化程序列表不会复制基础元素。

-end note]

An object of type initializer_list<E> provides access to an array of objects of type const E. [Note: A pair of pointers or a pointer plus a length would be obvious representations for initializer_list. initializer_list is used to implement initializer lists as specified in 8.5.4. Copying an initializer list does not copy the underlying elements.
—end note]

对于私有成员的实现 initializer_list 是非易失性的文字类型;然而,因为他们提到他们认为一对指针或一个指针和长度将是明显的表示,他们可能没有考虑到某人可能把一些非字面量的成员

So there is no requirement for the private members of the implementation of initializer_list to be non-volatile literal types; however, because they mention that they believe a pair of pointers or a pointer and a length would be the "obvious representation," they probably didn't consider that someone might put something non-literal in the members of initializer_list.

我会说这是cl和标准中的一个错误。

I'd say that it's both a bug in clang and the standard, probably.

这篇关于为什么不将`std :: initializer_list`定义为文字类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆