【问题标题】:Need clarification on definition of literal type需要澄清文字类型的定义
【发布时间】:2013-09-06 01:09:27
【问题描述】:

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

我很困惑什么是文字类型,什么不是。

【问题讨论】:

标签: c++


【解决方案1】:

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

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

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

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

【讨论】:

  • 什么是非文字类型的例子?
  • @Comrade: std::string.
  • 所以最常见的非文字类型是类类型,不包括上面答案中包含的特殊类类型。
  • @Comrade:是的。基本上,任何重要的构造逻辑(尤其是动态内存分配)都会使您的类型成为非文字类型。如果你愿意,对象的状态不能仅仅通过你写下的东西来表达;它还取决于对象的动态历史。
  • @KerrekSB 我想知道对类类型的第二个要求是否实际上是多余的。根据第三个,它要么是一个聚合并且没有这样的初始化器,要么它有一个 constexpr ctor,它需要与第二个相同。
【解决方案2】:

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

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

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

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

[dcl.init.aggr]/1

聚合是一个数组或类,没有用户提供的构造函数,没有用于非静态数据成员的 brace-or-equal-initializers,没有私有或受保护的非静态数据成员,没有基类,也没有虚函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-10
    相关资源
    最近更新 更多