Namespaces
Variants

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

From cppreference.net
C++ named requirements

Spezifiziert, dass ein Typ ein Literaltyp ist. Literaltypen sind die Typen von constexpr Variablen und sie können in constexpr Funktionen konstruiert, manipuliert und zurückgegeben werden.

Hinweis: Der Standard definiert keine benannte Anforderung mit diesem Namen. Dies ist eine Typkategorie, die durch die Kernsprache definiert wird. Sie wird hier nur der Konsistenz halber als benannte Anforderung aufgeführt.

Inhaltsverzeichnis

Anforderungen

Ein Literaltyp ist einer der Folgenden:

  • möglicherweise cv-qualifiziertes void (damit constexpr Funktionen void zurückgeben können);
(seit C++14)
  • hat einen trivialen (bis C++20) constexpr (seit C++20) Destruktor ,
  • alle seine nicht-statischen nicht-varianten Datenmember und Basisklassen sind von nicht-flüchtigen Literaltypen, und
  • ist einer der folgenden
(seit C++17)
  • keine Varianten-Member besitzt, oder
  • mindestens einen Varianten-Member von nicht-flüchtigem Literaltyp hat,
  • keine Varianten-Member besitzt, oder
  • mindestens einen Varianten-Member von nicht-flüchtigem Literaltyp hat,
  • ein Typ mit mindestens einem constexpr (möglicherweise Template-)Konstruktor, der kein Kopier- oder Verschiebungskonstruktor ist.

Hinweise

Ein Typ kann literal sein, selbst wenn alle seine constexpr-Konstruktoren gelöscht, unzugänglich sind oder nicht an der Überladungsauflösung teilnehmen können.

struct A { constexpr A(int) = delete; char c; }; // A ist ein Literaltyp
constexpr A v = std::bit_cast<A>('0'); // OK in C++20
                                       // v hat Literaltyp und kann daher constexpr sein

Beispiel

Literaler Typ, der String-Literale erweitert:

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

Ausgabe:

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

Fehlerberichte

Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR Angewendet auf Verhalten wie veröffentlicht Korrigiertes Verhalten
CWG 1453 C++11 eine Literalklasse konnte volatile-Datenmitglieder haben nicht erlaubt
CWG 1951 C++11
C++14
es war unklar, ob cv-qualifizierte void (C++14)
und Klassentypen (C++11) Literaltypen sind
sie sind es
CWG 2096 C++11 damit ein Union-Typ literal ist, müssen alle seine nicht-
statischen Datenmitglieder literal sein
nur ein nicht-statisches Daten-
mitglied muss es sein
CWG 2598 C++11 damit ein Union-Typ literal ist, muss er
mindestens ein nicht-statisches Datenmitglied haben
er kann kein nicht-
statisches Datenmitglied haben

Siehe auch

(C++11) (deprecated in C++17) (removed in C++20)
prüft, ob ein Typ ein Literaltyp ist
(Klassentemplate)