C++ named requirements: LiteralType (since C++11)
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:
|
(seit C++14) |
- Skalartyp ;
- Referenztyp ;
- ein Array von Literaltyp;
- möglicherweise cv-qualifizierter Klassentyp, der alle folgenden Eigenschaften besitzt:
-
- 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) |
-
-
- ein Aggregat -Union-Typ, der
-
- keine Varianten-Member besitzt, oder
- mindestens einen Varianten-Member von nicht-flüchtigem Literaltyp hat,
- ein Nicht-Union- Aggregat -Typ, und jeder seiner anonymen Union -Member
-
- 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) |