Namespaces
Variants

Extending the namespace std

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

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::hash für programmdefinierte Typen müssen die Hash -Anforderungen erfüllen.
  • Spezialisierungen von std::atomic müssen einen gelöschten Kopierkonstruktor, einen gelöschten Kopierzuweisungsoperator und einen constexpr-Wertkonstruktor besitzen.
  • Spezialisierungen von std::istreambuf_iterator müssen einen trivialen Kopierkonstruktor, einen constexpr-Standardkonstruktor und einen trivialen Destruktor besitzen.
(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.

Funktionsschablonen und Elementfunktionen von Schablonen

Es ist erlaubt, Template-Spezialisierungen für jede Standardbibliothek-Funktionsvorlage zum Namensraum std hinzuzufügen, nur wenn die Deklaration von mindestens einem programmdefinierten Typ abhängt und die Spezialisierung alle Anforderungen der ursprünglichen Vorlage erfüllt, außer wo solche Spezialisierungen verboten sind.

(bis C++20)

Es ist undefiniertes Verhalten, eine vollständige Spezialisierung einer beliebigen Standardbibliothek-Funktionsvorlage zu deklarieren.

(seit C++20)

Es ist undefiniertes Verhalten, eine vollständige Spezialisierung einer beliebigen Memberfunktion einer Standardbibliothek-Klassenvorlage zu deklarieren:

Es ist undefiniertes Verhalten, eine vollständige Spezialisierung einer beliebigen Member-Funktionsvorlage einer Standardbibliotheksklasse oder Klassenvorlage zu deklarieren:

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++20)
(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.

Weitere Einschränkungen

Der Namensraum std darf nicht als ein Inline-Namensraum deklariert werden.

Adressierungsbeschränkung

Das 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