2016-10-29 15 views
2

Warum gibt es im folgenden Code keinen schweren Fehler? Typ Alias ​​und Name der Klasse sind genau die gleiche (Compiler clang):Ausgearbeiteter Typspezifizierer im Typalias

using S = struct S; 

struct S {}; 

S s; 

int main() 
{ 
} 

Weichen Namen genau in der Definition der Variablen in dem folgenden Code (Symbol oder Typ Alias) verwendet?

using S = struct S {}; 

int main() 
{ 
    S s; 
} 
+0

Da C und sein 'typedef struct S {} S;' –

+2

'using S = struct S;' verbirgt nicht, aber * definiert * 'S' neu, um ein typedef Name und ein Klassenname zu sein (ein einzelner Name, der zwei Eigenschaften hat). Sie werden oft Leute sagen hören, dass 'mit S = struct S;' zwei Namen einführt und C++ mehrere "symbol spaces" durchsucht, aber so funktioniert es in C++ nicht. Eine aufschlussreiche Diskussion hierzu finden Sie unter http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#407. –

Antwort

2

Der folgende Code macht S ein Alias ​​eines struct namens S. Die using S definiert den Namen S als Alias ​​von struct S neu.

using S = struct S; 

Die folgende Zeile definiert das struct S.

struct S {}; 

Die Erklärung unten, verwendet die S, der als Alias ​​S wie durch Verwendung gemacht.

S s; 

gelinde gesagt, dies ist vergleichbar mit dem

using K = struct S; 

struct S { S(){ std::cout << "Constructed!\n"; } }; 

K s; 

int main() 
{ } 

Der Code gedruckt wird:

Constructed! 

Grundsätzlich wird der Name K durch struct S ersetzt werden.


Für Ihr zweites Beispiel seines von Natur aus dem gleichen wie C der typedef:

typedef struct C {} C; 

, die einfach redundant in C++

2
  1. Das erste ist ein Überbleibsel aus C, in dem Tag-Namensraum (struct/union/enum) vom Type-Name-Namensraum (typedef und eingebauten Typen) vollständig getrennt ist.
    In C++ ist diese Regel gelockert. Wenn also im typename-Namespace nichts vorhanden ist, wird automatisch der Tag-Namespace durchsucht.

  2. Die zweite wird beantwortet, indem die Antwort für die erste:
    Der Typname gefunden wird.

+0

WRT 1. so geben Aliase Funktionen wie eine '# definieren '? Nur ein Textersatz? – Orient

+0

Nicht ganz so, dann gäbe es nicht zwei etwas getrennte Namensräume. Wie auch immer, #define ist böse. – Deduplicator

+0

'mit S = struct S;' führt zwei Namen in zwei verschiedenen Nachschlagetabellen ein (aus Sicht des Compilers)? – Orient

Verwandte Themen