Extending the namespace
std
Inhaltsverzeichnis |
Hinzufügen von Deklarationen zu
std
Es ist undefiniertes Verhalten, Deklarationen oder Definitionen zum Namensraum
std
oder zu einem beliebigen innerhalb von
std
geschachtelten Namensraum hinzuzufügen, mit wenigen unten aufgeführten Ausnahmen.
#include <utility> namespace std { // Eine Funktionsdefinition, die zum Namespace std hinzugefügt wurde: undefiniertes Verhalten pair<int, int> operator+(pair<int, int> a, pair<int, int> b) { return {a.first + b.first, a.second + b.second}; } }
Hinzufügen von Template-Spezialisierungen
Klassentemplates
Es ist erlaubt, Template-Spezialisierungen für jede Standardbibliothek-Klassentemplate zum Namensraum
std
hinzuzufügen, nur wenn die Deklaration von mindestens einem
programmdefinierten Typ
abhängt und die Spezialisierung alle Anforderungen des ursprünglichen Templates erfüllt, außer wo solche Spezialisierungen verboten sind.
// Deklaration der primären std::hash-Vorlage einbinden. // Wir dürfen sie nicht selbst deklarieren. // <typeindex> garantiert das Vorhandensein einer solchen Deklaration, // und ist deutlich günstiger einzubinden als <functional>. #include <typeindex> // Spezialisiere std::hash, damit MyType als Schlüssel in // std::unordered_set und std::unordered_map verwendet werden kann. // Das Öffnen des std-Namensraums kann unbeabsichtigt undefiniertes Verhalten verursachen // und ist für die Spezialisierung von Klassenvorlagen nicht erforderlich. template<> struct std::hash<MyType> { std::size_t operator()(const MyType& t) const { return t.hash(); } };
- Das Spezialisieren der Vorlage std::complex für andere Typen als float , double und long double ist nicht spezifiziert.
- Spezialisierungen von std::numeric_limits müssen alle in der primären Template deklarierten Member definieren, und zwar so, dass sie als integral constant expressions verwendbar sind.
|
(seit C++11) |
|
(bis C++17) |
Es ist undefiniertes Verhalten, eine vollständige oder teilweise Spezialisierung eines beliebigen Member-Klassentemplates einer Standardbibliotheksklasse oder Klassentemplate zu deklarieren.
|
Dieser Abschnitt ist unvollständig
Grund: Mini-Beispiel |
Funktionsschablonen und Elementfunktionen von Schablonen
|
Es ist erlaubt, Template-Spezialisierungen für jede Standardbibliothek-Funktionsvorlage zum Namensraum
|
(bis C++20) |
|
Es ist undefiniertes Verhalten, eine vollständige Spezialisierung einer beliebigen Standardbibliothek-Funktionsvorlage zu deklarieren. |
(seit C++20) |
|
Dieser Abschnitt ist unvollständig
Grund: Mini-Beispiel |
Es ist undefiniertes Verhalten, eine vollständige Spezialisierung einer beliebigen Memberfunktion einer Standardbibliothek-Klassenvorlage zu deklarieren:
|
Dieser Abschnitt ist unvollständig
Grund: Mini-Beispiel |
Es ist undefiniertes Verhalten, eine vollständige Spezialisierung einer beliebigen Member-Funktionsvorlage einer Standardbibliotheksklasse oder Klassenvorlage zu deklarieren:
|
Dieser Abschnitt ist unvollständig
Grund: Mini-Beispiel |
Variablen-Templates
|
Es ist undefiniertes Verhalten, eine vollständige oder partielle Spezialisierung einer beliebigen Standardbibliothek-Variablentemplate zu deklarieren, außer wo ausdrücklich erlaubt.
|
(seit C++14) |
Explizite Instanziierung von Templates
Es ist erlaubt, eine class (since C++20) -Template aus der Standardbibliothek explizit zu instanziieren, nur wenn die Deklaration vom Namen mindestens eines program-defined type abhängt und die Instanziierung den Standardbibliotheksanforderungen für das ursprüngliche Template entspricht.
|
Dieser Abschnitt ist unvollständig
Grund: Mini-Beispiel |
Weitere Einschränkungen
Der Namensraum
std
darf nicht als ein
Inline-Namensraum
deklariert werden.
AdressierungsbeschränkungDas Verhalten eines C++-Programms ist unspezifiziert (möglicherweise fehlerhaft), wenn es explizit oder implizit versucht, einen Zeiger, eine Referenz (für freie Funktionen und statische Memberfunktionen) oder einen Zeiger-auf-Member (für nicht-statische Memberfunktionen) auf eine Standardbibliotheksfunktion oder eine Instanziierung einer Standardbibliotheksfunktionsvorlage zu bilden, es sei denn, sie ist als adressierbare Funktion gekennzeichnet (siehe unten). Der folgende Code war in C++17 wohldefiniert, führt jedoch seit C++20 zu unspezifiziertem Verhalten und kompiliert möglicherweise nicht: #include <cmath> #include <memory> int main() { // durch unären Operator& auto fptr0 = &static_cast<float(&)(float, float)>(std::betaf); // durch std::addressof auto fptr1 = std::addressof(static_cast<float(&)(float, float)>(std::betaf)); // durch Funktion-zu-Zeiger implizite Konvertierung auto fptr2 = static_cast<float(&)(float)>(std::riemann_zetaf); // Bildung einer Referenz auto& fref = static_cast<float(&)(float)>(std::riemann_zetaf); } Designierte adressierbare Funktionen
|
(seit C++20) |
Fehlerberichte
Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | Angewendet auf | Verhalten wie veröffentlicht | Korrektes Verhalten |
|---|---|---|---|
| LWG 120 | C++98 |
Benutzer konnten Standardbibliothek-Vorlagen explizit
für nicht-benutzerdefinierte Typen instanziieren |
verboten |
| LWG 232 | C++98 |
Benutzer konnten Standardbibliothek-Vorlagen explizit spezialisieren,
wenn die Deklaration von einem benutzerdefinierten Namen mit externer Verknüpfung abhing (der auf einen nicht-benutzerdefinierten Typ verweisen kann) |
nur erlaubt für
benutzerdefinierte Typen |
| LWG 422 | C++98 |
Benutzer konnten einzelne Member oder Member-Vorlagen spezialisieren,
ohne die gesamte Standardbibliotheksklasse oder Klassenvorlage zu spezialisieren |
das Verhalten ist
in diesem Fall undefiniert |