C++ именованные требования: LiteralType (с C++11)
Указывает, что тип является литеральным типом. Литеральные типы — это типы constexpr переменных, и их можно создавать, обрабатывать и возвращать из constexpr функций.
Примечание: стандарт не определяет именованное требование с таким названием. Это категория типов, определяемая основным языком. Она включена здесь как именованное требование только для согласованности.
Требования
Литеральный тип — это любой из следующих типов:
| (с C++14) |
- скалярный тип;
- тип ссылки;
- массив литерального типа;
- потенциально cv-квалифицированный класс-тип, который обладает всеми следующими свойствами:
- имеет тривиальный(до C++20)
constexpr(с C++20) деструктор, - является одним из
| (с C++17) |
- агрегатный тип объединения, который
- не имеет членов-вариантов, или
- имеет хотя бы один член-вариант не-volatile литерального типа,
- не-объединение агрегатный тип, и каждый из его анонимных членов-объединений
- не имеет членов-вариантов, или
- имеет хотя бы один член-вариант не-volatile литерального типа,
- тип с, по крайней мере, одним
constexpr(возможно, шаблонным) конструктором, который не является конструктором копирования или перемещения,
Примечания
Тип может быть литеральным, даже если все его constexpr-конструкторы удалены, недоступны или не могут участвовать в разрешении перегрузки.
struct A { constexpr A(int) = delete; char c; }; // A is a literal type
constexpr A v = std::bit_cast<A>('0'); // OK in C++20
// v has literal type and thus can be 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 | Применено к | Поведение, как опубликовано | Правильное поведение |
|---|---|---|---|
| CWG 1453 | C++11 | литеральный класс мог иметь члены данных volatile | не разрешается |
| CWG 1951 | C++11 C++14 | не было ясно, являются ли cv-квалифицированные void (C++14)и классы-типы (C++11) литеральными типами | являются |
| CWG 2096 | C++11 | для того, чтобы тип объединения был литеральным, все его члены данных, не являющиеся статическими, должны быть литеральными | достаточно одного нестатического члена данных |
| CWG 2598 | C++11 | для того, чтобы тип объединения был литеральным, он должен иметь хотя бы один нестатический член данных | он может не иметь нестатических членов данных |
См. также
|
(C++11)(устарело в C++17)(удалено в C++20) | проверяет, является ли тип литеральным типом (шаблон класса) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/named_req/LiteralType