[basic.scope.pdecl]/7:
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-seqoptidentifier
;
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.
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.
Simply:
namespace ns {
// declares S into ns as per [basic.scope.pdecl]
void f(struct S&);
}
extern ns::S s;
//extern ::S s; // not declared
Here struct S
is first declared in the elaborated-type-specifier in a parameter-declaration-clause of a function defined in namespace scope, with the form class-key identifier
, and therefore [basic.scope.pdecl]/7.2 applies and struct S
is declared in the namespace ns
where the function is declared.
you'll have to use an object of class
S
in your functionf
Here is an example:
// ... continuing from previous example ...
namespace ns {
struct S {
int i;
};
void f(S& s) {
std::cout << s.i;
}
}
As a bonus, an example where the class is not first declared in the elaborated-type-specifier, and so the quoted rule does not apply:
struct S;
namespace ns {
void f(struct S&); // refers to ::S
}
//extern ns::S s; // not declared
extern ::S s;
Here, the elaborated-type-specifier is not the first declaration of struct S
, so [basic.scope.pdecl]/7 does not apply, and no class is declared into the 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With