P
Paul Bibbings
In §11.5.1 of TC++PL (Special Edition, 2000), "Finding Friends,"
Stroustrup says:
"Like a member declaration, a friend declaration does not
introduce a name into an enclosing scope."
A few lines earlier in the introduction to the section (11.5,
"Friends") he'd explicitly compared friend function declarations to
member function declarations, saying:
"Like a member function, a friend function is explicitly declared
in the declaration of the class of which it is a friend. It is
therefore as much a part of that interface as is a member function."
This is confusing me a little when I find, through working examples,
that the contrary of his first statement 'appears' to be the case,
despite his overall emphasis on the similarity of the two cases. Thus,
to simplify his example to working code, consider:
#include <iostream>
namespace N {
class C {
char *_c;
public:
C(char *c): _c(c) { }
friend void f(C); // friend function
void g(); // member function
};
void (*p)(C) = &f; // [Stroustrup - error: no f()
in scope] compiles fine, with definition below
}
// adding the definitions ...
void N::f(C c) { // friend scope: N::
std::cout << c._c << '\n';
}
void N::C::g() { // member scope: N::C::
std::cout << "In g()..." << '\n';
}
int main() {
N::C c("Hello, World!");
f(c); // uses the type of
parameter c to locate f() in N::
c.g();
return 0;
}
As the definitions of member g() and friend f() show, whereas g is
scoped in this example to the class definition, that is to N::C::, f
is scoped to N::, which I would see as the "enclosing scope" of C. So
I'm a little confused by his "LIKE a member declaration, a friend
declaration does NOT introduce a name into an enclosing scope."
Rather, unlike the member declaration, the friend declaration seems to
being doing just that, unless I am not understanding his words
correctly.
Furthermore, the definition of the function pointer is supposed to
fail, there being "no f() in scope." Of course, without the definition
of f below this it does indeed fail at linking, but with the
definition of f in place as above, everything appears to be fine.
Very possibly I'm merely missing the intent of his meaning, but I'm
struggling to find a sense that better fits his words. In particular,
where the example he gives does not explicitly include namespacing,
thus putting f() in the global namespace, it's hard to see exactly
what "enclosing scope" it doesn't go in to.
Note: The above has compiled for me with gcc 3.4.4 (cygwin) and cl v.
15.00.30729.01 (VC++ Express), just in case this is a non-standard
compiler issue.
Any help with understanding this would be greatly appreciated.
Regards PB
Stroustrup says:
"Like a member declaration, a friend declaration does not
introduce a name into an enclosing scope."
A few lines earlier in the introduction to the section (11.5,
"Friends") he'd explicitly compared friend function declarations to
member function declarations, saying:
"Like a member function, a friend function is explicitly declared
in the declaration of the class of which it is a friend. It is
therefore as much a part of that interface as is a member function."
This is confusing me a little when I find, through working examples,
that the contrary of his first statement 'appears' to be the case,
despite his overall emphasis on the similarity of the two cases. Thus,
to simplify his example to working code, consider:
#include <iostream>
namespace N {
class C {
char *_c;
public:
C(char *c): _c(c) { }
friend void f(C); // friend function
void g(); // member function
};
void (*p)(C) = &f; // [Stroustrup - error: no f()
in scope] compiles fine, with definition below
}
// adding the definitions ...
void N::f(C c) { // friend scope: N::
std::cout << c._c << '\n';
}
void N::C::g() { // member scope: N::C::
std::cout << "In g()..." << '\n';
}
int main() {
N::C c("Hello, World!");
f(c); // uses the type of
parameter c to locate f() in N::
c.g();
return 0;
}
As the definitions of member g() and friend f() show, whereas g is
scoped in this example to the class definition, that is to N::C::, f
is scoped to N::, which I would see as the "enclosing scope" of C. So
I'm a little confused by his "LIKE a member declaration, a friend
declaration does NOT introduce a name into an enclosing scope."
Rather, unlike the member declaration, the friend declaration seems to
being doing just that, unless I am not understanding his words
correctly.
Furthermore, the definition of the function pointer is supposed to
fail, there being "no f() in scope." Of course, without the definition
of f below this it does indeed fail at linking, but with the
definition of f in place as above, everything appears to be fine.
Very possibly I'm merely missing the intent of his meaning, but I'm
struggling to find a sense that better fits his words. In particular,
where the example he gives does not explicitly include namespacing,
thus putting f() in the global namespace, it's hard to see exactly
what "enclosing scope" it doesn't go in to.
Note: The above has compiled for me with gcc 3.4.4 (cygwin) and cl v.
15.00.30729.01 (VC++ Express), just in case this is a non-standard
compiler issue.
Any help with understanding this would be greatly appreciated.
Regards PB