C++ named requirements: LiteralType (since C++11)
Указывает, что тип является
литеральным типом
. Литеральные типы — это типы
constexpr
переменных
, и они могут быть созданы, использованы и возвращены из
constexpr
функций
.
Примечание: стандарт не определяет именованное требование с таким названием. Это категория типов, определяемая ядром языка. Она включена сюда как именованное требование только для обеспечения единообразия.
Содержание |
Требования
Литеральный тип — это любой из следующих:
|
(начиная с C++14) |
- скалярный тип ;
- ссылочный тип ;
- массив array литерального типа;
- возможно cv-квалифицированный классовый тип, обладающий всеми следующими свойствами:
-
- имеет тривиальный (до C++20) constexpr (начиная с C++20) деструктор ,
- все его нестатические невариантные члены данных и базовые классы являются не-volatile литеральными типами, и
- является одним из
|
(начиная с C++17) |
-
-
- агрегатный тип объединения , который
-
- не имеет вариантных членов , или
- имеет по крайней мере один вариантный член не-volatile литерального типа,
- не-объединенный агрегатный тип, и каждый из его анонимных объединений
-
- не имеет вариантных членов , или
- имеет по крайней мере один вариантный член не-volatile литерального типа,
- тип с по крайней мере одним constexpr (возможно шаблонным) конструктором, который не является конструктором копирования или перемещения.
-
Примечания
Тип может быть литеральным, даже если все его constexpr конструкторы удалены, недоступны или не могут участвовать в разрешении перегрузки.
struct A { constexpr A(int) = delete; char c; }; // A является литеральным типом constexpr A v = std::bit_cast<A>('0'); // OK в C++20 // v имеет литеральный тип и поэтому может быть constexpr
Пример
Литеральный тип, расширяющий строковые литералы:
#include <cstddef> #include <iostream> #include <stdexcept> class conststr // conststr is a literal type { const char* p; std::size_t sz; public: template<std::size_t N> constexpr conststr(const char(&a)[N]) : p(a), sz(N - 1) {} constexpr char operator[](std::size_t n) const { return n < sz ? p[n] : throw std::out_of_range(""); } constexpr std::size_t size() const { return sz; } }; constexpr std::size_t count_lower(conststr s) { std::size_t c{}; for (std::size_t n{}; n != s.size(); ++n) if ('a' <= s[n] && s[n] <= 'z') ++c; return c; } // An output function that requires a compile-time constant N, for testing template<int N> struct constN { constN() { std::cout << N << '\n'; } }; int main() { std::cout << "The number of lowercase letters in \"Hello, world!\" is "; constN<count_lower("Hello, world!")>(); // the string literal is implicitly // converted to conststr }
Вывод:
The number of lowercase letters in "Hello, world!" is 9
Отчеты о дефектах
Следующие отчеты об изменениях поведения, влияющие на дефекты, были применены ретроактивно к ранее опубликованным стандартам C++.
| DR | Applied to | Behavior as published | Correct behavior |
|---|---|---|---|
| CWG 1453 | C++11 | literal class could have volatile data members | not allowed |
| CWG 1951 |
C++11
C++14 |
it was unclear whether cv-qualified
void
(C++14)
and class types (C++11) are literal types |
they are |
| CWG 2096 | C++11 |
for a union type to be literal, all its non-
static data members must be literal |
only one non-static data
member needs to be |
| CWG 2598 | C++11 |
for a union type to be literal, it must have
at least one non-static data member |
it can have no non-
static data member |
Смотрите также
|
(C++11)
(deprecated in C++17)
(removed in C++20)
|
проверяет, является ли тип литеральным типом
(шаблон класса) |