Namespaces
Variants

C++ named requirements: LiteralType (since C++11)

From cppreference.net
C++ named requirements

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

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

Содержание

Требования

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

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