Namensräume
Varianten
Aktionen

C++ benannte Anforderungen: LiteralType (seit C++11)

Von cppreference.com
 
 
C++ benannte Anforderungen
 

Gibt an, dass ein Typ ein Literal-Typ ist. Literal-Typen 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 von der Kernsprache definierte Typkategorie. Sie ist hier nur der Konsistenz halber als benannte Anforderung enthalten.

Inhalt

[bearbeiten] Anforderungen

Ein Literal-Typ ist einer der folgenden Typen

  • möglicherweise cv-qualifiziertes void (damit constexpr Funktionen void zurückgeben können);
(seit C++14)
  • skalarer Typ;
  • Referenztyp;
  • ein Array eines Literal-Typs;
  • möglicherweise cv-qualifizierter Klassentyp, der alle folgenden Eigenschaften besitzt
  • besitzt einen trivialen(bis C++20)constexpr(seit C++20) Destruktor,
  • alle seine nicht-statischen, nicht-varianten Datenmember und Basisklassen sind von nicht-volatilen Literal-Typen, und
  • ist einer der folgenden Typen
(seit C++17)
  • keine Variantenmember hat, oder
  • mindestens einen Variantenmember eines nicht-volatilen Literal-Typs hat,
  • keine Variantenmember hat, oder
  • mindestens einen Variantenmember eines nicht-volatilen Literal-Typs hat,
  • ein Typ mit mindestens einem constexpr (möglicherweise Template-) Konstruktor, der kein Kopier- oder Verschiebekonstruktor ist.

[bearbeiten] Hinweise

Ein Typ kann ein Literal-Typ sein, auch wenn alle seine constexpr-Konstruktoren gelöscht, unzugänglich oder nicht an der Überladungsauflösung beteiligt sind.

struct A { constexpr A(int) = delete; char c; }; // A is a literal type
constexpr A v = std::bit_cast<A>('0'); // OK in C++20
                                       // v has literal type and thus can be constexpr

[bearbeiten] Beispiel

Literal-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

[bearbeiten] Defect reports

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 Datenmember haben nicht erlaubt
CWG 1951 C++11
C++14
es war unklar, ob cv-qualifiziertes void (C++14)
und Klassentypen (C++11) Literal-Typen sind
sie sind
CWG 2096 C++11 damit ein Union-Typ ein Literal-Typ ist, müssen alle seine Nicht-
statischen Datenmember Literal-Typen sein
nur ein Nicht-Static-Daten-
Mitglied muss
CWG 2598 C++11 damit ein Union-Typ ein Literal-Typ ist, muss er
mindestens ein Nicht-Static-Datenmember haben
er kann keine Nicht-
statischen Datenmember haben

[bearbeiten] Siehe auch

(C++11)(in C++17 veraltet)(in C++20 entfernt)
prüft, ob ein Typ ein Literal-Typ ist
(Klassenvorlage) [bearbeiten]