Topic: Does friend class declaration also declare the class?
Author: dhb2000@gmail.com (Barry)
Date: Tue, 23 Oct 2007 17:20:44 GMT Raw View
struct A
{
friend class X;
X* px;
};
void F(X*)
{
}
int main()
{
}
Comuea refuses it, says:
identifier "X" is undefined
<std>
9.1/3
An elaborated-type-specifier (7.1.5.3) can also be used as a
type-specifier as part of a declaration.
9.1/4
The declaration of a class name takes effect immediately after the
identifier is seen in the class definition or elaborated-type-specifier.
</std>
void Fun(class X* p)
{
}
class X {};
int main()
{
X x;
Fun(&x);
}
/////////////////////////////
Literally, friend class granting also falls into 9.1/4.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: =?iso-8859-1?q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Tue, 23 Oct 2007 15:11:18 CST Raw View
On 23 Okt., 19:20, dhb2...@gmail.com (Barry) wrote:
> struct A
> {
> friend class X;
> X* px;
> };
>
> void F(X*)
> {
> }
>
> int main()
> {
> }
>
> Comuea refuses it, says:
> identifier "X" is undefined
Comeau is correct here.
> <std>
> 9.1/3
> An elaborated-type-specifier (7.1.5.3) can also be used as a
> type-specifier as part of a declaration.
> 9.1/4
> The declaration of a class name takes effect immediately after the
> identifier is seen in the class definition or elaborated-type-specifier.
> </std>
>
> void Fun(class X* p)
> {
>
> }
>
> class X {};
>
> int main()
> {
> X x;
> Fun(&x);
>
> }
>
> /////////////////////////////
>
> Literally, friend class granting also falls into 9.1/4.
No, because this condition is not sufficient. A friend-declaration
uses a "decl-specifierseq of the form friend elaborated-type-
specifier" ([class.mem]/7) and [class.friend]/2 says that
"An elaborated-type-specifier shall be used in a friend declaration
for a class". This does not mean that a friend declaration has the
same properties as other declarations using a
elaborated-type-specifier.
Your example not equivalent to that shown above.
Your adapted example - that should compile - would be:
struct A
{
friend class X;
class X* px;
};
void F(X*)
{
}
int main()
{
}
Note that the elaborated-type-specifier used to define A::px does
bring the name X into the scope, while the previous friend-declaration
does not so. This is clarified by two further paragraphs related to
friend declarations:
[basic.scope.pdecl]/6:
"[Note: friend declarations refer to functions or classes that are
members
of the nearest enclosing namespace, but they do not introduce new
names
into that namespace (7.3.1.2).[..]"
and [namespace.memdef]/3:
"Every name first declared in a namespace is a member of that
namespace.
If a friend declaration in a non-local class first declares a class
or
function 83) the friend class or function is a member of the innermost
enclosing namespace. The name of the friend is not found by simple
name
lookup until a matching declaration is provided in that namespace
scope
(either before or after the class declaration granting friendship).
[..]"
This behaviour is by design, because otherwise every friend-
declaration
would bring names into the outer-scope which would participate in the
look-up.
Greetings from Bremen,
Daniel Kr gler
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]