C++ benannte Anforderungen: LiteralType (seit C++11)
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
|
(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) |
- ein Aggregat-Union-Typ, der
- keine Variantenmember hat, oder
- mindestens einen Variantenmember eines nicht-volatilen Literal-Typs hat,
- ein nicht-Union Aggregat-Typ, und jeder seiner anonymen Union-Member
- 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) |