Namespaces
Variants

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

From cppreference.net
C++ named requirements

Especifica que un tipo es un tipo literal . Los tipos literales son los tipos de constexpr variables y pueden ser construidos, manipulados y devueltos desde constexpr funciones .

Nota: el estándar no define un requisito nombrado con este nombre. Esta es una categoría de tipo definida por el lenguaje central. Se incluye aquí como un requisito nombrado solo por consistencia.

Contenidos

Requisitos

Un tipo literal es cualquiera de los siguientes:

  • posiblemente calificado cv void (para que las funciones constexpr puedan retornar void);
(desde C++14)
  • tiene un trivial (hasta C++20) constexpr (desde C++20) destructor ,
  • todos sus miembros de datos no estáticos no variantes y clases base son de tipos literales no volátiles, y
  • es uno de
(desde C++17)
  • un tipo con al menos un constructor constexpr (posiblemente plantilla) que no es un constructor de copia o movimiento.

Notas

Un tipo puede ser literal incluso si todos sus constructores constexpr están eliminados, son inaccesibles o no pueden participar en la resolución de sobrecarga.

struct A { constexpr A(int) = delete; char c; }; // A es un tipo literal
constexpr A v = std::bit_cast<A>('0'); // Válido en C++20
                                       // v tiene tipo literal y por lo tanto puede ser constexpr

Ejemplo

Tipo literal que extiende los literales de cadena:

#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
}

Salida:

The number of lowercase letters in "Hello, world!" is 9

Informes de defectos

Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares publicados anteriormente de C++.

DR Aplicado a Comportamiento publicado Comportamiento correcto
CWG 1453 C++11 una clase literal podría tener miembros de datos volátiles no permitido
CWG 1951 C++11
C++14
no estaba claro si los tipos void calificados cv (C++14)
y tipos de clase (C++11) son tipos literales
lo son
CWG 2096 C++11 para que un tipo unión sea literal, todos sus miembros
de datos no estáticos deben ser literales
solo un miembro de datos no estático
necesita serlo
CWG 2598 C++11 para que un tipo unión sea literal, debe tener
al menos un miembro de datos no estático
puede no tener ningún miembro
de datos no estático

Véase también

(C++11) (deprecated in C++17) (removed in C++20)
verifica si un tipo es un tipo literal
(plantilla de clase)