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                      ]