Namespaces
Variants

Unqualified name lookup

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

Für einen unqualifizierten Namen, also einen Namen, der nicht rechts eines Bereichsauflösungsoperators :: erscheint, untersucht die Namenssuche die Bereiche wie unten beschrieben, bis sie mindestens eine Deklaration jeglicher Art findet, woraufhin die Suche beendet wird und keine weiteren Bereiche mehr untersucht werden. (Hinweis: Die Suche aus manchen Kontexten überspringt einige Deklarationen, zum Beispiel ignoriert die Suche des Namens, der links von :: verwendet wird, Funktions-, Variablen- und Enumeratordeklarationen; die Suche eines Namens, der als Basisklassenspezifizierer verwendet wird, ignoriert alle Nicht-Typ-Deklarationen).

Zum Zweck der unqualifizierten Namenssuche erscheinen alle Deklarationen aus einem durch eine using-Direktive nominierten Namespace so, als wären sie im nächstgelegenen einschließenden Namespace deklariert, der direkt oder indirekt sowohl die using-Direktive als auch den nominierten Namespace enthält.

Die Suche nach unqualifizierten Namen für den Namen links vom Funktionsaufrufoperator (und äquivalenter Operator in einem Ausdruck) wird beschrieben in argument-dependent lookup .

Inhaltsverzeichnis

Dateibereich

Für einen Namen, der im globalen (Top-Level-Namespace) Bereich verwendet wird, außerhalb jeglicher Funktion, Klasse oder benutzerdeklarierten Namespaces, wird der globale Bereich vor der Verwendung des Namens überprüft:

int n = 1;     // Deklaration von n
int x = n + 1; // OK: Suche findet ::n
int z = y - 1; // Fehler: Suche schlägt fehl
int y = 2;     // Deklaration von y

Namespace-Bereich

Für einen Namen, der in einem benutzerdeklarierten Namespace außerhalb einer Funktion oder Klasse verwendet wird, wird dieser Namespace vor der Verwendung des Namens durchsucht, dann der diesen Namespace umschließende Namespace vor der Deklaration dieses Namespace, usw. bis der globale Namespace erreicht ist.

int n = 1; // Deklaration
namespace N
{
    int m = 2;
    namespace Y
    {
        int x = n; // OK, Suche findet ::n
        int y = m; // OK, Suche findet ::N::m
        int z = k; // Fehler: Suche schlägt fehl
    }
    int k = 3;
}

Definition außerhalb seines Namensraums

Für einen Namen, der in der Definition einer Namespace-Member-Variable außerhalb des Namespace verwendet wird, erfolgt die Suche auf die gleiche Weise wie für einen Namen, der innerhalb des Namespace verwendet wird:

namespace X
{
    extern int x; // Deklaration, keine Definition
    int n = 1;    // zuerst gefunden
}
int n = 2;        // zweitens gefunden
int X::x = n;     // findet X::n, setzt X::x auf 1

Definition einer Nicht-Mitgliedsfunktion

Für einen Namen, der in der Definition einer Funktion verwendet wird, entweder in ihrem Körper oder als Teil eines Standardarguments, wobei die Funktion ein Mitglied eines benutzerdeklarierten oder globalen Namespace ist, wird der Block, in dem der Name verwendet wird, vor der Verwendung des Namens durchsucht, dann wird der umschließende Block vor dem Beginn dieses Blocks durchsucht usw., bis der Block erreicht wird, der den Funktionskörper darstellt. Dann wird der Namespace, in dem die Funktion deklariert ist, bis zur Definition (nicht notwendigerweise der Deklaration) der Funktion, die den Namen verwendet, durchsucht, dann die umschließenden Namespaces usw.

namespace A
{
    namespace N
    {
        void f();
        int i = 3; // gefunden als 3. (wenn 2. nicht vorhanden)
    }
    int i = 4;     // gefunden als 4. (wenn 3. nicht vorhanden)
}
int i = 5;         // gefunden als 5. (wenn 4. nicht vorhanden)
void A::N::f()
{
    int i = 2;     // gefunden als 2. (wenn 1. nicht vorhanden)
    while (true)
    {
       int i = 1;  // gefunden als 1.: Suche ist abgeschlossen
       std::cout << i;
    }
}
// int i;          // nicht gefunden
namespace A
{
    namespace N
    {
        // int i;  // nicht gefunden
    }
}

Klassendefinition

Für einen Namen, der überall in der Klassendefinition verwendet wird (einschließlich Basisklassenspezifizierer und verschachtelte Klassendefinitionen), außer innerhalb eines Member-Funktionskörpers, eines Standardarguments einer Member-Funktion, einer Ausnahmespezifikation einer Member-Funktion oder eines Standard-Member-Initialisierers, wobei der Member zu einer verschachtelten Klasse gehören kann, deren Definition sich im Körper der einschließenden Klasse befindet, werden die folgenden Geltungsbereiche durchsucht:

a) der Rumpf der Klasse, in dem der Name verwendet wird, bis zum Verwendungspunkt,
b) den gesamten Körper seiner Basisklasse(n), wobei rekursiv in deren Basen gesucht wird, wenn keine Deklarationen gefunden werden,
c) wenn diese Klasse geschachtelt ist, der Rumpf der umschließenden Klasse bis zur Definition dieser Klasse und der gesamte Rumpf der Basisklasse(n) der umschließenden Klasse,
d) wenn diese Klasse lokal ist oder in einer lokalen Klasse geschachtelt ist, der Blockgültigkeitsbereich, in dem die Klasse definiert ist, bis zum Punkt der Definition,
e) wenn diese Klasse ein Mitglied eines Namensraums ist oder in einer Klasse geschachtelt ist, die ein Mitglied eines Namensraums ist, oder eine lokale Klasse in einer Funktion ist, die ein Mitglied eines Namensraums ist, wird der Gültigkeitsbereich des Namensraums bis zur Definition der Klasse, der umschließenden Klasse oder Funktion durchsucht; die Suche setzt sich in den diesen umschließenden Namensräumen fort, bis zum globalen Gültigkeitsbereich.

Für eine friend -Deklaration verläuft die Suche zur Bestimmung, ob sie auf eine zuvor deklarierte Entität verweist, wie oben beschrieben, mit der Ausnahme, dass sie nach dem innersten umschließenden Namespace stoppt.

namespace M
{
    // const int i = 1; // niemals gefunden
    class B
    {
        // static const int i = 3;     // als 3. gefunden (wird jedoch Zugriffsprüfung nicht bestehen)
    };
}
// const int i = 5;                    // als 5. gefunden
namespace N
{
    // const int i = 4;                // als 4. gefunden
    class Y : public M::B
    {
        // static const int i = 2;     // als 2. gefunden
        class X
        {
            // static const int i = 1; // als 1. gefunden
            int a[i]; // Verwendung von i
            // static const int i = 1; // niemals gefunden
        };
        // static const int i = 2;     // niemals gefunden
    };
    // const int i = 4;                // niemals gefunden
}
// const int i = 5;                    // niemals gefunden

Eingefügter Klassenname

Für den Namen einer Klasse oder eines Klassentemplates, der innerhalb der Definition dieser Klasse oder dieses Templates oder einer davon abgeleiteten verwendet wird, findet die unqualified name lookup die Klasse, die definiert wird, als ob der Name durch eine Member-Deklaration (mit public member access) eingeführt wurde. Für weitere Details siehe injected-class-name .

Definition der Member-Funktion

Für einen Namen, der innerhalb eines Member-Funktionskörpers, eines Standardarguments einer Member-Funktion, einer Exception-Spezifikation einer Member-Funktion oder eines Standard-Member-Initialisierers verwendet wird, sind die durchsuchten Geltungsbereiche dieselben wie in der Klassendefinition , mit der Ausnahme, dass der gesamte Geltungsbereich der Klasse betrachtet wird, nicht nur der Teil vor der Deklaration, die den Namen verwendet. Für geschachtelte Klassen wird der gesamte Körper der umschließenden Klasse durchsucht.

class B
{
    // int i;         // gefunden als 3.
};
namespace M
{
    // int i;         // gefunden als 5.
    namespace N
    {
        // int i;     // gefunden als 4.
        class X : public B
        {
            // int i; // gefunden als 2.
            void f();
            // int i; // ebenfalls gefunden als 2.
        };
        // int i;     // gefunden als 4.
    }
}
// int i;             // gefunden als 6.
void M::N::X::f()
{
    // int i;         // gefunden als 1.
    i = 16;
    // int i;         // nie gefunden
}
namespace M
{
    namespace N
    {
        // int i;     // nie gefunden
    }
}
In jedem Fall gelten beim Untersuchen der Basen, von denen die Klasse abgeleitet ist, die folgenden Regeln, manchmal auch als Dominanz in der virtuellen Vererbung bezeichnet:
Ein Member-Name, der in einem Subobjekt B gefunden wird, verdeckt denselben Member-Namen in jedem Subobjekt A , falls A ein Basisklassen-Subobjekt von B ist. (Beachten Sie, dass dies den Namen in keinen zusätzlichen, nicht-virtuellen Kopien von A im Vererbungsgitter verdeckt, die keine Basen von B sind: Diese Regel hat nur bei virtueller Vererbung einen Effekt.) Namen, die durch using-Deklarationen eingeführt werden, werden als Namen in der Klasse behandelt, die die Deklaration enthält. Nach der Überprüfung jeder Basis muss der resultierende Satz entweder Deklarationen eines static-Members aus Subobjekten desselben Typs oder Deklarationen von non-static-Members aus demselben Subobjekt enthalten. (bis C++11)
Ein Lookup-Set wird konstruiert, das aus den Deklarationen und den Subobjekten besteht, in denen diese Deklarationen gefunden wurden. Using-Deklarationen werden durch die Member, die sie repräsentieren, ersetzt und Typdeklarationen, einschließlich injizierter Klassennamen, werden durch die Typen ersetzt, die sie repräsentieren. Wenn C die Klasse ist, in deren Gültigkeitsbereich der Name verwendet wurde, wird C zuerst untersucht. Wenn die Liste der Deklarationen in C leer ist, wird für jede ihrer direkten Basen Bi eine Lookup-Set erstellt (unter rekursiver Anwendung dieser Regeln, falls Bi eigene Basen hat). Nach der Erstellung werden die Lookup-Sets für die direkten Basen wie folgt in die Lookup-Set in C zusammengeführt:
  • wenn der Satz der Deklarationen in Bi leer ist, wird er verworfen,
  • wenn die bisher erstellte Lookup-Set von C leer ist, wird sie durch die Lookup-Set von Bi ersetzt,
  • wenn jedes Subobjekt in der Lookup-Set von Bi eine Basis von mindestens einem der Subobjekte ist, die bereits zur Lookup-Set von C hinzugefügt wurden, wird die Lookup-Set von Bi verworfen,
  • wenn jedes Subobjekt, das bereits zur Lookup-Set von C hinzugefügt wurde, eine Basis von mindestens einem Subobjekt in der Lookup-Set von Bi ist, dann wird die Lookup-Set von C verworfen und durch die Lookup-Set von Bi ersetzt,
  • andernfalls, wenn die Deklarationssätze in Bi und in C unterschiedlich sind, ist das Ergebnis eine ambivalente Zusammenführung: Die neue Lookup-Set von C hat eine ungültige Deklaration und eine Vereinigung der Subobjekte, die früher in C zusammengeführt und aus Bi eingeführt wurden. Diese ungültige Lookup-Set ist möglicherweise kein Fehler, wenn sie später verworfen wird,
  • andernfalls hat die neue Lookup-Set von C die gemeinsamen Deklarationssätze und die Vereinigung der Subobjekte, die früher in C zusammengeführt und aus Bi eingeführt wurden.
(seit C++11)
struct X { void f(); };
struct B1: virtual X { void f(); };
struct B2: virtual X {};
struct D : B1, B2
{
    void foo()
    {
        X::f(); // OK, ruft X::f auf (qualifizierte Suche)
        f(); // OK, ruft B1::f auf (unqualifizierte Suche)
    }
};
// C++98-Regeln: B1::f verdeckt X::f, daher wird X::f, obwohl es von D aus
// über B2 erreichbar ist, durch Namenssuche von D aus nicht gefunden.
// C++11-Regeln: Suchmenge für f in D findet nichts, fährt mit Basen fort
//  Suchmenge für f in B1 findet B1::f und wird abgeschlossen
// Merge ersetzt die leere Menge, jetzt enthält Suchmenge für f in C B1::f in B1
//  Suchmenge für f in B2 findet nichts, fährt mit Basen fort
//    Suche für f in X findet X::f
//  Merge ersetzt die leere Menge, jetzt enthält Suchmenge für f in B2 X::f in X
// Merge in C stellt fest, dass jedes Subobjekt (X) in der Suchmenge in B2 eine Basis
// jedes bereits gemergten Subobjekts (B1) ist, daher wird die B2-Menge verworfen
// C bleibt nur mit B1::f gefunden in B1 übrig
// (wenn struct D : B2, B1 verwendet würde, dann würde der letzte Merge C's
//  bisher gemergtes X::f in X *ersetzen*, weil jedes bereits zu C hinzugefügte
//  Subobjekt (nämlich X) eine Basis von mindestens einem Subobjekt in der neuen
//  Menge (B1) wäre; das Endergebnis wäre dasselbe: Suchmenge in C enthält
//  nur B1::f gefunden in B1)
Unqualifizierte Namenssuche, die statische Member von B , geschachtelte Typen von B und in B deklarierte Enumeratoren findet, ist eindeutig, selbst wenn es mehrere nicht-virtuelle Basis-Subobjekte vom Typ B in der Vererbungshierarchie der untersuchten Klasse gibt:
struct V { int v; };
struct B
{
    int a;
    static int s;
    enum { e };
};
struct B1 : B, virtual V {};
struct B2 : B, virtual V {};
struct D : B1, B2 {};
void f(D& pd)
{
    ++pd.v;       // OK: nur ein v, da nur ein virtuelles Basis-Subobjekt
    ++pd.s;       // OK: nur ein static B::s, obwohl in B1 und B2 gefunden
    int i = pd.e; // OK: nur ein Enumerator B::e, obwohl in B1 und B2 gefunden
    ++pd.a;       // Fehler, mehrdeutig: B::a in B1 und B::a in B2
}

Friend-Funktionsdefinition

Für einen Namen, der in einer friend -Funktionsdefinition innerhalb des Klassenkörpers verwendet wird, der die Freundschaft gewährt, erfolgt die unqualifizierte Namenssuche auf die gleiche Weise wie für eine Memberfunktion. Für einen Namen, der in einer friend -Funktion verwendet wird, die außerhalb des Klassenkörpers definiert ist, erfolgt die unqualifizierte Namenssuche auf die gleiche Weise wie für eine Funktion in einem Namespace.

int i = 3;                     // gefunden 3. für f1, gefunden 2. für f2
struct X
{
    static const int i = 2;    // gefunden 2. für f1, nie gefunden für f2
    friend void f1(int x)
    {
        // int i;              // gefunden 1.
        i = x;                 // findet und modifiziert X::i
    }
    friend int f2();
    // static const int i = 2; // gefunden 2. für f1 überall im Klassenbereich
};
void f2(int x)
{
    // int i;                  // gefunden 1.
    i = x;                     // findet und modifiziert ::i
}

Friend-Funktionsdeklaration

Für einen Namen, der im Deklarator einer friend -Funktionsdeklaration verwendet wird, die eine Memberfunktion einer anderen Klasse als Freund deklariert: Wenn der Name nicht Teil eines Template-Arguments im Deklarator -Bezeichner ist, untersucht die unqualifizierte Namenssuche zunächst den gesamten Gültigkeitsbereich der Klasse der Memberfunktion. Wenn er in diesem Gültigkeitsbereich nicht gefunden wird (oder wenn der Name Teil eines Template-Arguments im Deklarator-Bezeichner ist), setzt sich die Suche fort, wie für eine Memberfunktion der Klasse, die die Freundschaft gewährt.

template<class T>
struct S;
// die Klasse, deren Memberfunktionen als Friend deklariert werden
struct A
{ 
    typedef int AT;
    void f1(AT);
    void f2(float);
    template<class T>
    void f3();
    void f4(S<AT>);
};
// die Klasse, die Friend-Zugriff für f1, f2 und f3 gewährt
struct B
{
    typedef char AT;
    typedef float BT;
    friend void A::f1(AT);    // Suche nach AT findet A::AT (AT wurde in A gefunden)
    friend void A::f2(BT);    // Suche nach BT findet B::BT (BT wurde nicht in A gefunden)
    friend void A::f3<AT>();  // Suche nach AT findet B::AT (keine Suche in A, weil
                              //     AT im Deklarator-Identifier A::f3<AT> enthalten ist)
};
// die Klassenvorlage, die Friend-Zugriff für f4 gewährt
template<class AT>
struct C
{
    friend void A::f4(S<AT>); // Suche nach AT findet A::AT
                              // (AT ist nicht im Deklarator-Identifier A::f4 enthalten)
};

Standardargument

Für einen Namen, der in einem Default-Argument in einer Funktionsdeklaration verwendet wird, oder einen Namen, der im Ausdruck eines Member-Initialisierers eines Konstruktors verwendet wird, werden die Funktionsparameternamen zuerst gefunden, bevor die umschließenden Block-, Klassen- oder Namensraumbereiche untersucht werden:

class X
{
    int a, b, i, j;
public:
    const int& r;
    X(int i): r(a),      // initialisiert X::r als Referenz auf X::a
              b(i),      // initialisiert X::b mit dem Wert des Parameters i
              i(i),      // initialisiert X::i mit dem Wert des Parameters i
              j(this->i) // initialisiert X::j mit dem Wert von X::i
    {}
};
int a;
int f(int a, int b = a); // Fehler: Suche nach a findet Parameter a, nicht ::a
                         // und Parameter sind als Standardargumente nicht erlaubt

Definition statischer Datenelemente

Für einen Namen, der in der Definition eines static data member verwendet wird, erfolgt die Suche auf die gleiche Weise wie für einen Namen, der in der Definition einer Member-Funktion verwendet wird.

struct X
{
    static int x;
    static const int n = 1; // zuerst gefunden
};
int n = 2;                  // zweitens gefunden
int X::x = n;               // findet X::n, setzt X::x auf 1, nicht 2

Enumeratordeklaration

Für einen Namen, der im Initialisierungsteil der Enumerator-Deklaration verwendet wird, werden zuerst die zuvor deklarierten Enumeratoren in derselben Enumeration gefunden, bevor die unqualifizierte Namenssuche fortfährt, um den umschließenden Block, Klassen- oder Namensraum-Bereich zu untersuchen.

const int RED = 7;
enum class color
{
    RED,
    GREEN = RED + 2, // RED findet color::RED, nicht ::RED, also GREEN = 2
    BLUE = ::RED + 4 // qualifizierte Suche findet ::RED, BLUE = 11
};

Handler eines Funktions- try -Blocks

Für einen Namen, der im Handler eines Funktion- try Blocks verwendet wird, erfolgt die Namenssuche so, als ob der Name ganz am Anfang des äußersten Blocks des Funktionsrumpfs verwendet würde (insbesondere sind Funktionsparameter sichtbar, aber Namen, die in diesem äußersten Block deklariert wurden, sind nicht sichtbar)

int n = 3;          // gefunden 3.
int f(int n = 2)    // gefunden 2.
try
{
    int n = -1;     // nie gefunden
}
catch(...)
{
    // int n = 1;   // gefunden 1.
    assert(n == 2); // Suche nach n findet Funktionsparameter f
    throw;
}

Überladener Operator

Für einen Operator , der in einem Ausdruck verwendet wird (z.B. operator + in a + b ), gelten leicht unterschiedliche Lookup-Regeln gegenüber dem Operator in einem expliziten Funktionsaufruf wie operator + ( a, b ) : Beim Parsen eines Ausdrucks werden zwei separate Lookups durchgeführt: für Nicht-Member-Operator-Überladungen und für Member-Operator-Überladungen (für Operatoren, bei denen beide Formen erlaubt sind). Diese Mengen werden dann gleichberechtigt mit den integrierten Operator-Überladungen zusammengeführt, wie in Overload Resolution beschrieben. Bei Verwendung der expliziten Funktionsaufruf-Syntax wird ein regulärer unqualifizierter Name-Lookup durchgeführt:

struct A {};
void operator+(A, A);  // benutzerdefinierter Nicht-Member-operator+
struct B
{
    void operator+(B); // benutzerdefinierter Member-operator+
    void f();
};
A a;
void B::f() // Definition einer Member-Funktion von B
{
    operator+(a, a); // Fehler: Reguläre Namenssuche aus einer Member-Funktion
                     // findet die Deklaration von operator+ im Gültigkeitsbereich von B
                     // und stoppt dort, ohne den globalen Gültigkeitsbereich zu erreichen
    a + a; // OK: Member-Suche findet B::operator+, Nicht-Member-Suche
           // findet ::operator+(A, A), Überladungsauflösung wählt ::operator+(A, A)
}

Template-Definition

Für einen nicht-abhängigen Namen , der in einer Templatedefinition verwendet wird, erfolgt die unqualifizierte Namenssuche, wenn die Templatedefinition geprüft wird. Die Bindung an die Deklarationen, die zu diesem Zeitpunkt vorgenommen wurden, wird nicht durch Deklarationen beeinflusst, die zum Zeitpunkt der Instanziierung sichtbar sind. Für einen abhängigen Namen , der in einer Templatedefinition verwendet wird, wird die Suche verschoben, bis die Templateargumente bekannt sind. Zu diesem Zeitpunkt untersucht ADL Funktionsdeklarationen mit externer Bindung (bis C++11) , die sowohl vom Templatedefinitionskontext als auch vom Templateinstanziierungskontext sichtbar sind, während die Nicht-ADL-Suche nur Funktionsdeklarationen mit externer Bindung (bis C++11) untersucht, die vom Templatedefinitionskontext sichtbar sind (mit anderen Worten: Das Hinzufügen einer neuen Funktionsdeklaration nach der Templatedefinition macht sie nicht sichtbar, außer über ADL). Das Verhalten ist undefiniert, wenn es in den durch die ADL-Suche untersuchten Namensräumen eine bessere Übereinstimmung mit externer Bindung gibt, die in einer anderen Übersetzungseinheit deklariert ist, oder wenn die Suche mehrdeutig gewesen wäre, wenn diese Übersetzungseinheiten geprüft worden wären. In jedem Fall wird, wenn eine Basisklasse von einem Templateparameter abhängt, ihr Gültigkeitsbereich nicht durch die unqualifizierte Namenssuche untersucht (weder zum Zeitpunkt der Definition noch zum Zeitpunkt der Instanziierung).

void f(char); // erste Deklaration von f
template<class T> 
void g(T t)
{
    f(1);    // nicht-abhängiger Name: Suche findet ::f(char) und bindet es jetzt
    f(T(1)); // abhängiger Name: Suche wird verschoben
    f(t);    // abhängiger Name: Suche wird verschoben
//  dd++;    // nicht-abhängiger Name: Suche findet keine Deklaration
}
enum E { e };
void f(E);   // zweite Deklaration von f
void f(int); // dritte Deklaration von f
double dd;
void h()
{
    g(e);  // instanziiert g<E>, zu diesem Zeitpunkt
           // werden die zweite und dritte Verwendung des Namens 'f'
           // gesucht und finden ::f(char) (durch Namenssuche) und ::f(E) (durch ADL)
           // dann wählt die Überladungsauflösung ::f(E).
           // Dies ruft f(char), dann f(E) zweimal auf
    g(32); // instanziiert g<int>, zu diesem Zeitpunkt
           // werden die zweite und dritte Verwendung des Namens 'f'
           // gesucht und finden nur ::f(char)
           // dann wählt die Überladungsauflösung ::f(char)
           // Dies ruft f(char) dreimal auf
}
typedef double A;
template<class T>
class B
{
    typedef int A;
};
template<class T>
struct X : B<T>
{
    A a; // Suche nach A findet ::A (double), nicht B<T>::A
};

Hinweis: siehe dependent name lookup rules für die Begründung und Implikationen dieser Regel.

Vorlagenname

Element einer Klassenvorlage außerhalb der Vorlage

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 490 C++98 jeder Name in einem Template-Argument in einer friend
Member-Funktionsdeklaration wurde nicht im
Gültigkeitsbereich der Member-Funktionsklasse gesucht
schließt nur die Namen
in Template-Argumenten im
Deklarator-Identifier aus
CWG 514 C++98 jeder unqualifizierte Name, der im Namespace-
Gültigkeitsbereich verwendet wurde, wurde zuerst in diesem Gültigkeitsbereich gesucht
die unqualifizierten Namen, die zur Definition eines
Namespace-Variablen-Members außerhalb dieses
Namespace verwendet werden, werden zuerst in diesem Namespace gesucht

Referenzen

  • C++23-Standard (ISO/IEC 14882:2024):
  • 6.5 Namenssuche [basic.lookup] (S: 44-45)
  • 6.5.2 Mitgliedsnamenssuche [class.member.lookup] (S: 45-47)
  • 13.8 Namensauflösung [temp.res] (S: 399-403)
  • C++20-Standard (ISO/IEC 14882:2020):
  • 6.5 Namenssuche [basic.lookup] (S: 38-50)
  • 11.8 Elementnamenssuche [class.member.lookup] (S: 283-285)
  • 13.8 Namensauflösung [temp.res] (S: 385-400)
  • C++17-Standard (ISO/IEC 14882:2017):
  • 6.4 Namenssuche [basic.lookup] (S: 50-63)
  • 13.2 Mitgliedsnamenssuche [class.member.lookup] (S: 259-262)
  • 17.6 Namensauflösung [temp.res] (S: 375-378)
  • C++14-Standard (ISO/IEC 14882:2014):
  • 3.4 Namenssuche [basic.lookup] (S: 42-56)
  • 10.2 Mitgliedsnamenssuche [class.member.lookup] (S: 233-236)
  • 14.6 Namensauflösung [temp.res] (S: 346-359)
  • C++11-Standard (ISO/IEC 14882:2011):
  • 3.4 Namenssuche [basic.lookup]
  • 10.2 Mitgliedsnamenssuche [class.member.lookup]
  • 14.6 Namensauflösung [temp.res]
  • C++98 Standard (ISO/IEC 14882:1998):
  • 3.4 Namenssuche [basic.lookup]
  • 10.2 Mitgliedsnamenssuche [class.member.lookup]
  • 14.6 Namensauflösung [temp.res]

Siehe auch