The point of declaration of a class first declared in an elaborated-type-specifier is as follows:
(7.1) for a declaration of the form
class-key attribute-specifier-seqopt identifier
;
the identifier is declared to be a class-name in the scope that contains the declaration, otherwise
(7.2) for an elaborated-type-specifier of the form
class-key identifier
if the elaborated-type-specifier is used in the decl-specifier-seq or
parameter-declaration-clause of a function defined in namespace scope, the identifier is declared as a class-name in the namespace that contains the declaration; otherwise, except as a friend declaration, the identifier is declared in the smallest namespace or block scope that contains the declaration. [ Note: These rules also apply within templates. — end note ] [ Note: Other forms of elaborated-type-specifier do not declare a new name, and therefore must refer to an existing type-name. See [basic.lookup.elab] and [dcl.type.elab].— end note ]
Consider the case (7.2) above where the elaborated-type-specifier is used in the decl-specifier-seq of a parameter-declaration-clause of a function defined in namespace scope. How would that conciliate with the fact that this elaborated-type-specifier must be the first declaration of the class in its namespace?
Consider the example (demo) below:
File prog.cc
:
struct S;
extern S s;
int S;
void f(struct S&); // The elaborated-type-specififer `struct S` is not
// the first declaration in the global namespace and
// if we eliminate the first declaration `struct S;`
// on the top, the code doesn't compile !!
int main(){
f(s);
}
File other.cc
:
#include<iostream>
struct S{
int i = 1;
};
void f(struct S& s) { std::cout << s.i << '\n'; }
S s;
Note that the code above compiles and executes correctly, but the elaborated-type-specififer in the parameter-declaration-clause of function f
is not the first in the global namespace.
Assuming that my interpretation about [basic.scope.pdecl]/7 is correct, I would like to see an example showing the application of paragraph (7.2) above, where the alluded declaration would be the first in its namespace.
if we eliminate the first declaration
struct S;
on the top, the code doesn't compile !!
Well that's because you still need to declare a name before you use it.
int S;
void f(struct S&);
extern struct S s; // If you write this line before then it
// will not compile.
// The name still needs to be declared
// before you use it.
// If you drop the `int S` above, then the following
// will also compile, since S has already been declared
// extern S s2;
int main(){
f(s);
}
Note that the code above compiles and executes correctly, but the elaborated-type-specififer in the parameter-declaration-clause of function
f
is not the first in the global namespace.
I don't understand the point you're trying to make here. Since it's not the first, no name is declared and [basic.scope.pdecl]p7 doesn't apply.
I would like to see an example showing the application of paragraph (7.2) above, where the alluded declaration would be the first in its namespace.
auto addrof(struct S& s) { // First declaration
return &s;
}
int get(struct T&); // First declaration