Topic: typedefs in friend declarations


Author: "Gene Bushuyev" <gbush@my-deja.com>
Date: 1999/12/22
Raw View
"Scott Meyers" <smeyers@aristeia.com> wrote in message
news:MPG.12c18ebaab27aa76989710@news.teleport.com...
>
> Consider the following code:
>
>   template <class T>      // some class template
>   class A {
>     T* a;
>   };
>
>   class B {
>     typedef A<B> C;       // C is a typedef for A<B>
>     friend class C;       // declare A<B> as a friend
>   };
>
> Is this kosher?  Everybody's favorite whipping boy, MSVC, rejects it, but
> g++, como, and CodeWarrior all accept it.  My reading of the standard
> suggests that the kids in Redmond may be right.

Since my previous reply from a few days ago never made it the newsgroup I
allow myself to repeat it.
There is nothing wrong with this code per se. But it does something
different than you expect. With that friend declaration you declare a class
C to be a friend of class B, it's not A<B> that was declared a friend. So
you have typedef C hiding class C in the scope of B and if you need to
access it you would have to use the elaborated name.

--
Gene Bushuyev
Entia non sunt multiplicanda praeter necessitatem
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: wmm@fastdial.net
Date: 1999/12/20
Raw View
In article <MPG.12c18ebaab27aa76989710@news.teleport.com>,
  smeyers@aristeia.com (Scott Meyers) wrote:
>
> Consider the following code:
>
>   template <class T>      // some class template
>   class A {
>     T* a;
>   };
>
>   class B {
>     typedef A<B> C;       // C is a typedef for A<B>
>     friend class C;       // declare A<B> as a friend
>   };
>
> Is this kosher?  Everybody's favorite whipping boy, MSVC, rejects it,
but
> g++, como, and CodeWarrior all accept it.  My reading of the standard
> suggests that the kids in Redmond may be right.
>
> Paragraph 2 of 11.4 says, in part:
>
>   An  elaborated-type-specifier shall be used in a friend declaration
>   for a class.
>
> 7.1.5.3 defines elaborated type specifiers:
>
>   1    elaborated-type-specifier:
>                class-key ::opt nested-name-specifieropt identifier
>                enum ::opt nested-name-specifieropt identifier
>                typename ::opt  nested-name-specifier identifier
>                typename ::opt  nested-name-specifier templateopt
template-id
>
>   ...
>
>   3 _basic.lookup.elab_ describes how name lookup proceeds for the
identi-
>     fier in an elaborated-type-specifier.  If the identifier resolves
to a
>     class-name  or  enum-name, the elaborated-type-specifier
introduces it
>     into the declaration the same way a  simple-type-specifier
introduces
>     its type-name.  IF THE IDENTIFIER RESOLVES TO A TYPEDEF-NAME OR A
TEM-
>     PLATE TYPE-PARAMETER,  THE  ELABORATED-TYPE-SPECIFIER  IS  ILL-
FORMED.
>
> Have I overlooked something?

No, you're right.  You can't use a typedef name nor a template
parameter in an elaborated-type-specifier.

--
William M. Miller, wmm@fastdial.net
OnDisplay, Inc. (www.ondisplay.com)


Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: smeyers@aristeia.com (Scott Meyers)
Date: 1999/12/15
Raw View
Consider the following code:

  template <class T>      // some class template
  class A {
    T* a;
  };

  class B {
    typedef A<B> C;       // C is a typedef for A<B>
    friend class C;       // declare A<B> as a friend
  };

Is this kosher?  Everybody's favorite whipping boy, MSVC, rejects it, but
g++, como, and CodeWarrior all accept it.  My reading of the standard
suggests that the kids in Redmond may be right.

Paragraph 2 of 11.4 says, in part:

  An  elaborated-type-specifier shall be used in a friend declaration
  for a class.

7.1.5.3 defines elaborated type specifiers:

  1    elaborated-type-specifier:
               class-key ::opt nested-name-specifieropt identifier
               enum ::opt nested-name-specifieropt identifier
               typename ::opt  nested-name-specifier identifier
               typename ::opt  nested-name-specifier templateopt template-id

  ...

  3 _basic.lookup.elab_ describes how name lookup proceeds for the identi-
    fier in an elaborated-type-specifier.  If the identifier resolves to a
    class-name  or  enum-name, the elaborated-type-specifier introduces it
    into the declaration the same way a  simple-type-specifier  introduces
    its type-name.  IF THE IDENTIFIER RESOLVES TO A TYPEDEF-NAME OR A TEM-
    PLATE TYPE-PARAMETER,  THE  ELABORATED-TYPE-SPECIFIER  IS  ILL-FORMED.

Have I overlooked something?

Thanks,

Scott

PS - In case it matter, the above quotes are from the FDIS.

--
Scott Meyers, Ph.D.                  smeyers@aristeia.com
Software Development Consultant      http://www.aristeia.com/
Visit http://meyerscd.awl.com/ to demo the Effective C++ CD


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]