Spec-Zone.ru › C++

C++ именованные требования: LiteralType (с C++11)

Указывает, что тип является литеральным типом. Литеральные типы — это типы constexpr переменных, и их можно создавать, обрабатывать и возвращать из constexpr функций.

Примечание: стандарт не определяет именованное требование с таким названием. Это категория типов, определяемая основным языком. Она включена здесь как именованное требование только для согласованности.

Требования

Литеральный тип — это любой из следующих типов:

  • потенциально cv-квалифицированный void (чтобы constexpr функции могли возвращать void);
(с 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 для того, чтобы тип объединения был литеральным, он должен иметь
хотя бы один нестатический член данных
он может не иметь нестатических
членов данных

См. также

is_literal_type
(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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API