Namensräume
Varianten
Aktionen

Erweiterung des std-Namensraums

Von cppreference.com
< cpp‎ | Sprache
 
 
C++ Sprache
Allgemeine Themen
Kontrollfluss
Bedingte Ausführungsaussagen
if
Iterationsanweisungen (Schleifen)
for
Bereichs-for (C++11)
Sprunganweisungen
Funktionen
Funktionsdeklaration
Lambda-Funktionsausdruck
inline-Spezifizierer
Dynamische Ausnahmespezifikationen (bis C++17*)
noexcept-Spezifizierer (C++11)
Ausnahmen
Namensräume
Typen
Spezifizierer
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Speicherdauer-Spezifizierer
Initialisierung
Ausdrücke
Alternative Darstellungen
Literale
Boolesch - Ganzzahl - Gleitkommazahl
Zeichen - String - nullptr (C++11)
Benutzerdefinierte (C++11)
Dienstprogramme
Attribute (C++11)
Typen
typedef-Deklaration
Typalias-Deklaration (C++11)
Umwandlungen
Speicherzuweisung
Klassen
Klassenspezifische Funktionseigenschaften
explicit (C++11)
static

Spezielle Member-Funktionen
Templates
Sonstiges
 

Inhalt

[bearbeiten] Deklarationen zu std hinzufügen

Es ist undefiniertes Verhalten, Deklarationen oder Definitionen zum Namensraum std oder zu einem in std verschachtelten Namensraum hinzuzufügen, mit wenigen Ausnahmen, die unten aufgeführt sind.

#include <utility>
 
namespace std
{
    // a function definition added to namespace std: undefined behavior
    pair<int, int> operator+(pair<int, int> a, pair<int, int> b)
    {
        return {a.first + b.first, a.second + b.second};
    }
}

[bearbeiten] Template-Spezialisierungen hinzufügen

[bearbeiten] Klassentemplates

Es ist erlaubt, Template-Spezialisierungen für jedes Standardbibliotheks-Klassentemplate im Namensraum std hinzuzufügen, nur wenn die Deklaration von mindestens einem vom Programm definierten Typ abhängt und die Spezialisierung alle Anforderungen für das ursprüngliche Template erfüllt, es sei denn, solche Spezialisierungen sind untersagt.

// Get the declaration of the primary std::hash template.
// We are not permitted to declare it ourselves.
// <typeindex> is guaranteed to provide such a declaration, 
// and is much cheaper to include than <functional>.
 
#include <typeindex> 
 
// Specialize std::hash so that MyType can be used as a key in 
// std::unordered_set and std::unordered_map.  Opening namespace
// std can accidentally introduce undefined behavior, and is not
// necessary for specializing class templates.
template<>
struct std::hash<MyType>
{
    std::size_t operator()(const MyType& t) const { return t.hash(); }
};
  • Die Spezialisierung des Templates std::complex für jeden anderen Typ als float, double und long double ist nicht spezifiziert.
  • Spezialisierungen von std::hash für vom Programm definierte Typen müssen die Hash-Anforderungen erfüllen.
  • Spezialisierungen von std::atomic müssen einen gelöschten Kopierkonstruktor, einen gelöschten Zuweisungsoperator für Kopien und einen constexpr-Wertkonstruktor haben.
  • Spezialisierungen von std::istreambuf_iterator müssen einen trivialen Kopierkonstruktor, einen constexpr-Standardkonstruktor und einen trivialen Destruktor haben.
(seit C++11)
(bis C++17)

Es ist undefiniertes Verhalten, eine vollständige oder partielle Spezialisierung eines beliebigen Member-Klassentemplates einer Standardbibliotheksklasse oder eines Klassentemplates zu deklarieren.

[bearbeiten] Funktionstemplates und Member-Funktionen von Templates

Es ist erlaubt, Template-Spezialisierungen für jedes Standardbibliotheks-Funktionstemplate im Namensraum std hinzuzufügen, nur wenn die Deklaration von mindestens einem vom Programm definierten Typ abhängt und die Spezialisierung alle Anforderungen für das ursprüngliche Template erfüllt, es sei denn, solche Spezialisierungen sind untersagt.

(bis C++20)

Es ist undefiniertes Verhalten, eine vollständige Spezialisierung eines beliebigen Standardbibliotheks-Funktionstemplate zu deklarieren.

(seit C++20)

Es ist undefiniertes Verhalten, eine vollständige Spezialisierung einer beliebigen Member-Funktion einer Standardbibliotheks-Klassentemplate zu deklarieren.

Es ist undefiniertes Verhalten, eine vollständige Spezialisierung eines beliebigen Member-Funktionstemplate einer Standardbibliotheksklasse oder eines Klassentemplates zu deklarieren.

[bearbeiten] Variablentemplates

Es ist undefiniertes Verhalten, eine vollständige oder partielle Spezialisierung eines beliebigen Standardbibliotheks-Variablentemplates zu deklarieren, es sei denn, es ist ausdrücklich erlaubt.

(seit C++20)
(seit C++14)

[bearbeiten] Explizite Instanziierung von Templates

Es ist erlaubt, ein Klassen-(seit C++20)Template, das in der Standardbibliothek definiert ist, explizit zu instanziieren, nur wenn die Deklaration von mindestens einem vom Programm definierten Typ abhängt und die Instanziierung die Standardbibliotheksanforderungen für das ursprüngliche Template erfüllt.

[bearbeiten] Weitere Einschränkungen

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

Adressierungsbeschränkung

Das Verhalten eines C++-Programms ist nicht spezifiziert (möglicherweise fehlerhaft formuliert), wenn es explizit oder implizit versucht, einen Zeiger, eine Referenz (für freie Funktionen und statische Member-Funktionen) oder einen Zeiger-auf-Member (für nicht-statische Member-Funktionen) auf eine Standardbibliotheksfunktion oder eine Instanziierung eines Standardbibliotheks-Funktionstemplate zu bilden, es sei denn, sie wird als *adressierbare Funktion* (siehe unten) bezeichnet.

Der folgende Code war in C++17 gut formuliert, führt aber seit C++20 zu nicht spezifizierten Verhaltensweisen und kann möglicherweise nicht kompiliert werden.

#include <cmath>
#include <memory>
 
int main()
{
    // by unary operator&
    auto fptr0 = &static_cast<float(&)(float, float)>(std::betaf);
 
    // by std::addressof
    auto fptr1 = std::addressof(static_cast<float(&)(float, float)>(std::betaf));
 
    // by function-to-pointer implicit conversion
    auto fptr2 = static_cast<float(&)(float)>(std::riemann_zetaf);
 
    // forming a reference
    auto& fref = static_cast<float(&)(float)>(std::riemann_zetaf);
}

Bezeichnete adressierbare Funktionen

(seit C++20)

[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
LWG 120 C++98 Benutzer konnten Standardbibliotheks-
templates explizit für nicht-benutzerdefinierte Typen instanziieren.
verboten
LWG 232 C++98 Benutzer konnten Standardbibliotheks-Templates spezialisieren,
wenn die Deklaration von einem Benutzernamen mit
externer Verknüpfung abhing (der sich auf einen nicht-benutzerdefinierten Typ beziehen kann)
Nur erlaubt für
benutzerdefinierte Typen
LWG 422 C++98 Benutzer konnten einzelne Member oder Member-Templates spezialisieren
ohne die gesamte Standardbibliotheksklasse oder das gesamte Klassentemplate zu spezialisieren.
Das Verhalten ist
in diesem Fall nicht definiert.