C++ named requirements: LiteralType (since C++11)
Spécifie qu'un type est un
type littéral
. Les types littéraux sont les types des
constexpr
variables
et ils peuvent être construits, manipulés et retournés par des
constexpr
fonctions
.
Note : la norme ne définit pas d'exigence nommée avec ce nom. Il s'agit d'une catégorie de type définie par le langage de base. Elle est incluse ici comme exigence nommée uniquement par souci de cohérence.
Table des matières |
Exigences
Un type littéral est l'un des éléments suivants :
|
(depuis C++14) |
- type scalaire ;
- type référence ;
- un tableau de type littéral ;
- type classe éventuellement qualifié cv qui possède toutes les propriétés suivantes :
-
- possède un trivial (jusqu'à C++20) constexpr (depuis C++20) destructeur ,
- tous ses membres de données non statiques non-variants et classes de base sont de types littéraux non volatils, et
- est l'un des
|
(depuis C++17) |
-
-
- un type union agrégat qui
-
- n'a pas de membres variants , ou
- a au moins un membre variant de type littéral non-volatile,
- un type agrégat non-union, et chacun de ses membres union anonymes
-
- n'a pas de membres variants , ou
- a au moins un membre variant de type littéral non-volatile,
- un type avec au moins un constructeur constexpr (éventuellement template) qui n'est pas un constructeur de copie ou de déplacement.
-
Notes
Un type peut être littéral même si tous ses constructeurs constexpr sont supprimés, inaccessibles ou ne peuvent pas participer à la résolution de surcharge.
struct A { constexpr A(int) = delete; char c; }; // A est un type littéral constexpr A v = std::bit_cast<A>('0'); // OK en C++20 // v a un type littéral et peut donc être constexpr
Exemple
Type littéral qui étend les littéraux de chaîne :
#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 }
Sortie :
The number of lowercase letters in "Hello, world!" is 9
Rapports de défauts
Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.
| DR | Applicable à | Comportement publié | Comportement correct |
|---|---|---|---|
| CWG 1453 | C++11 | une classe littérale pouvait avoir des membres de données volatiles | non autorisé |
| CWG 1951 |
C++11
C++14 |
il n'était pas clair si les types
void
qualifiés cv (C++14)
et les types classe (C++11) sont des types littéraux |
ils le sont |
| CWG 2096 | C++11 |
pour qu'un type union soit littéral, tous ses membres
de données non statiques doivent être littéraux |
seulement un membre de données non statique
doit l'être |
| CWG 2598 | C++11 |
pour qu'un type union soit littéral, il doit avoir
au moins un membre de données non statique |
il peut n'avoir aucun membre
de données non statique |
Voir aussi
|
(C++11)
(déprécié en C++17)
(supprimé en C++20)
|
vérifie si un type est un type littéral
(modèle de classe) |