24

我正在阅读的书中经常提到,类型必须是文字类型才能在某些情况下使用,例如可以使用 constexpr 的类型。但给出的唯一定义是文字类型是算术、引用或指针类型。但是当我们定义一个 constexpr 类型时,它似乎必须用一个字面量或一个最初用字面量初始化的变量来初始化。

我对什么是文字类型感到困惑,什么不是。

4

2 回答 2

17

从 C++11、3.9/10 开始:

一个类型是文字类型,如果它是:

  • 标量类型;或者
  • 引用类型;或者
  • 文字类型的数组;或者
  • 具有以下所有属性的类类型(第 9 条):
    • 它有一个微不足道的析构函数,
    • 非静态数据成员(如果有)的大括号或等式初始化器中的每个构造函数调用和完整表达式都是常量表达式(5.19),
    • 它是一种聚合类型 (8.5.1) 或至少有一个不是复制或移动构造函数的 constexpr 构造函数或构造函数模板,并且
    • 它的所有非静态数据成员和基类都是文字类型。

所以基本上它要么是引用,要么是原始对象类型,或者可以从字面量类型以 constexpr 方式构造的东西(数组、聚合或具有 constexpr 构造函数的类)。

于 2013-09-02T22:19:35.353 回答
3

C++11 (n3485),[basic.types]9-10

算术类型、枚举类型、指针类型、指向成员类型的指针std::nullptr_t,以及这些类型的 cv 限定版本统称为标量类型[...]

一个类型是文字类型,如果它是:

  • 标量类型;或者
  • 引用类型;或者
  • 文字类型的数组;或者
  • 具有以下所有属性的类类型:
    • 它有一个微不足道的析构函数,
    • 非静态数据成员(如果有)的大括号或等式初始化器中的每个构造函数调用和完整表达式都是常量表达式,
    • 它是一种聚合类型或至少有一个constexpr构造函数或构造函数模板不是复制或移动构造函数,并且
    • 它的所有非静态数据成员和基类都是非易失性文字类型。

[dcl.init.aggr]/1

聚合是一个数组或类,没有用户提供的构造函数,没有用于非静态数据成员的大括号或等号初始化器,没有私有或受保护的非静态数据成员,没有基类,也没有虚函数。

于 2013-09-02T22:19:52.580 回答