2 Stimmen

Name lookup Klarstellung

10,2/4- "[ Hinweis: Das Suchen eines Namens in einem elaborierten Typspezifizierer (3.4.4) oder Basisspezifizierer (Klausel 10) ignoriert beispielsweise alle nichttypbezogenen Deklarationen, während das Suchen eines Namens in einem verschachtelten Namensspezifizierer (3.4.3) Funktionen, Variablen und Aufzählungsdarstellungen ignoriert."

Ich habe diese Aussage in diesem Abschnitt beim Beschreiben der Namenssuche als sehr verwirrend empfunden.

void S(){}

struct S{
   S(){cout << 1;}
   void f(){}
   static const int x = 0;
}; 

int main(){ 
   struct S *p = new struct ::S;  // hier bezieht sich ::S auf den Typ
   p->::S::f();

   S::x;  // Basisspezifizierer, ignoriert die Funktionsdeklaration 'S'

   ::S(); // verschachtelter Namensspezifizierer, ignoriert die Strukturdarstellung 'S'.
   delete p;
} 

Meine Fragen:

  1. Ist mein Verständnis der Regeln korrekt?

  2. Warum wird ::S in der Zeile mit new automatisch als struct S behandelt, während in der letzten Zeile ::S die Funktionen S im globalen Namensraum bedeutet.

  3. Weist dies auf eine Unklarheit in der Dokumentation hin oder ist es einfach wieder ein Tag, an dem ich mich vom C++-Standarddokument fernhalten sollte?

2 Stimmen

Aua. Der Compiler hätte bei etwa Zeile 3 stoppen sollen und dir sagen, dass du deinen Code überarbeiten solltest.

0 Stimmen

@Greg Hewgill: oh Gelöbnis!. Compiler und Refactoring. Innovation at its best!

0 Stimmen

>> Ist es schon wieder ein Tag für mich, mich fernzuhalten von C++ Standard Dokument? - Ja.

2voto

AProgrammer Punkte 49452

Q1: Ich denke schon.

Q2: Kompatibilität mit C. Wenn Sie in C eine struct deklarieren, ist der Tag-Name einfach nur ein Tag-Name. Um es eigenständig verwenden zu können, benötigen Sie ein typedef. In C++ benötigen Sie das typedef nicht, das macht das Leben einfacher. Aber die Regeln von C++ wurden durch die Notwendigkeit kompliziert, bereits vorhandene C-Header importieren zu können, die den Tag-Namen mit einem Funktionsnamen "überlastet" haben. Das klassische Beispiel dafür ist die Unix stat()-Funktion, die ein struct stat* als Argument verwendet.

Q3: Standard-Lektüre ist normalerweise ziemlich schwierig... Sie müssen bereits wissen, dass es anderswo keinen Ort gibt, an dem das, was Sie lesen, modifiziert wird. Es ist nicht seltsam, dass Leute, die wissen, wie man das macht, Sprachenrechtler sind...

0voto

Du irrst dich bezüglich des zweiten Kommentars. In S::x ist das S ein Name in einem verschachtelten Namensspezifizierer. Was im Standard mit "base-specifier" gemeint ist, lautet wie folgt

namespace B { struct X { }; void X() }
struct A : B::X { }; // B::X ist ein base-specifier

Du liegst auch falsch in Bezug auf dies:

::S(); // verschachtelter Namensspezifizierer, ignoriert die struct-Deklaration 'S'.

Der Code ruft die Funktion nicht auf, weil ::S ein verschachtelter Namensspezifizierer wäre (das ist es nicht!), sondern weil Funktionsnamen Klassen- oder Enumerationsnamen verdecken, wenn sowohl die Funktion als auch die Klasse/Enumeration im gleichen Geltungsbereich deklariert sind.

Zum Thema interessant wäre der folgende Code für Zeile 2 deines Hauptteils

p->S::f();

Wichtig ist, dass S einem :: vorausgeht, was dazu führt, dass die Suche die Funktion ignoriert. Dass du :: vor S setzt, hat in deinem Fall keine Auswirkung.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X