c++ - A class name introduced inside a class is not treated as a nested class name -
take these class definitions:
class definition 1:
struct { struct b* m_b; };
class definition 2:
struct { struct b; b* m_b; };
both class defintions should declare b
nested class. @ least, that's thought reading following draft c++11 standard:
9.1/2 class declaration introduces class name scope declared , hides class, variable, function, or other declaration of name in enclosing scope (3.3). if class name declared in scope variable, function, or enumerator of same name declared, when both declarations in scope, class can referred using elaborated-type-specifier `
however, g++ 4.8.2 treats them differently. in first definition, treats b
class peer a
.
the following program built successfully:
struct { struct b* m_b; }; void myfun(const b& b ) { } int main() { a; myfun(*a.m_b); }
while following program not:
struct { struct b; b* m_b; }; void myfun(const b& b ) { } int main() { a; myfun(*a.m_b); }
i understand why second program not compile don't understand why first program built successfully.
am missing in interpretation of standard?
is g++ 4.8.2 correct in compiling first program?
g++'s behavior here entirely correct. specified in §3.3.2 [basic.scope.pdecl]/p7 of standard:
the point of declaration of class first declared in elaborated-type-specifier follows:
- for declaration of form
class-key attribute-specifier-seqopt identifier ;
identifier declared class-name in scope contains declaration, otherwise- for elaborated-type-specifier of form
class-key identifier
if elaborated-type-specifier used in decl-specifier-seq or parameter-declaration-clause of function defined in namespace scope, identifier declared class-name in namespace contains declaration; otherwise, except friend declaration*, identifier declared in smallest namespace or block scope contains declaration.
note in second case declaration placed in namespace or block scope, never class scope, can never declare nested class. also, in second case, lookup performed , if declared type-name not found elaborated-type-specifier taken declare new name (§3.4.4 [basic.lookup.elab]/p2, §9.1 [class.name]/p3 note).
* friend declarations have own weird rules. names first declared in friend declarations still placed in namespace (for non-local classes) or block (for local classes) scope, not made visible name lookup (except adl in case of functions) until declared in scope containing them. rules non-local classes specified in §7.3.1.2 [namespace.memdef]/p3:
if friend declaration in non-local class first declares class or function friend class or function member of innermost enclosing namespace. name of friend not found unqualified lookup (3.4.1) or qualified lookup (3.4.3) until matching declaration provided in namespace scope (either before or after class definition granting friendship). if friend function called, name may found name lookup considers functions namespaces , classes associated types of function arguments (3.4.2). if name in friend declaration neither qualified nor template-id , declaration function or elaborated-type-specifier, lookup determine whether entity has been declared shall not consider scopes outside innermost enclosing namespace.
the rules local classes specified in §11.3 [class.friend]/p11:
if friend declaration appears in local class (9.8) , name specified unqualified name, prior declaration looked without considering scopes outside innermost enclosing non-class scope. [...] friend class declaration, if there no prior declaration, class specified belongs innermost enclosing non-class scope, if subsequently referenced, name not found name lookup until matching declaration provided in innermost enclosing non-class scope.
Comments
Post a Comment