Нужно уточнить определение литерального типа

В книге, которую я читаю, часто упоминается, что тип должен иметь тип литерала для использования в определенных ситуациях, таких как типы, которые могут использовать constexpr. Но единственным определением было то, что буквальные типы являются арифметическими, ссылочными или указательными типами. Но когда мы определяем тип constexpr, кажется, что он должен быть инициализирован литералом или переменной, которая была первоначально инициализирована литералом.

Я смущен тем, что квалифицируется как литерал, а что нет.

Ответы

Ответ 1

Из С++ 11, 3.9/10:

Тип - это буквальный тип, если он:

  • скалярный тип; или
  • ссылочный тип; или
  • массив литералов; или
  • тип класса (раздел 9), который имеет все следующие свойства:
    • он имеет тривиальный деструктор,
    • каждый вызов конструктора и полное выражение в инициализаторах скобок или равных для нестатических членов данных (если они есть) является постоянным выражением (5.19),
    • это тип агрегата (8.5.1) или имеет хотя бы один конструктор конструктора или конструктора constexpr, который не является конструктором копирования или перемещения, и
    • все его нестатические элементы данных и базовые классы имеют литеральные типы.

Таким образом, в основном это либо ссылочный, либо примитивный тип объекта, либо что-то, что может быть построено из литерала в виде constexpr (массивы, агрегаты или классы с конструктором constexpr).

Ответ 2

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

Арифметические типы, типы перечисления, типы указателей, указатели на типы членов, std::nullptr_t и cv-квалификационные версии этих типов в совокупности называются скалярными типами [...]

Тип - это буквальный тип, если он:

  • скалярный тип; или
  • ссылочный тип; или
  • массив литералов; или
  • тип класса, который обладает всеми следующими свойствами:
    • он имеет тривиальный деструктор,
    • каждый вызов конструктора и полноэкранное выражение в элементарных или равных инициализаторах для нестатических членов данных (если есть) является постоянным выражением,
    • является агрегированным типом или имеет хотя бы один конструктор конструктора или конструктора constexpr, который не является конструктором копирования или перемещения, и
    • все его нестатические элементы данных и базовые классы являются нелетучими литералами.

[dcl.init.aggr]/1

Агрегат - это массив или класс без конструкторов, не предоставляемых пользователем, без элементов с символом скобки или равными для нестатических членов данных, без частных или защищенных нестатических элементов данных, без базовых классов и без виртуальных функции.