C++ named requirements: LiteralType (since C++11)
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:
|
(desde C++14) |
- tipo escalar ;
- tipo de referencia ;
- un array de tipo literal;
- tipo de clase posiblemente calificado cv que tiene todas las siguientes propiedades:
-
- 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 de unión agregada que
-
- no tiene miembros variantes , o
- tiene al menos un miembro variante de tipo literal no volátil,
- un tipo agregado no unión, y cada uno de sus miembros de unión anónima
-
- no tiene miembros variantes , o
- tiene al menos un miembro variante de tipo literal no volátil,
- 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) |