Namespaces
Variants

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

From cppreference.net
C++ named requirements

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 :

  • éventuellement qualifié cv void (afin que les fonctions constexpr puissent renvoyer void);
(depuis C++14)
  • 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)
  • n'a pas de membres variants , ou
  • a au moins un membre variant de type littéral non-volatile,
  • 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)