Question

Does anyone know why typedefs of class names don't work like class names for the friend declaration?

class A
{
public:
};

class B : public A
{
public:
   typedef A SUPERCLASS;
};

typedef A X;

class C
{
public:
   friend class A;             // OK
   friend class X;             // fails
   friend class B::SUPERCLASS; // fails
};
Was it helpful?

Solution

It can't, currently. I don't know the reason yet (just looking it up, because i find it interesting). Update: you can find the reason in the first proposal to support typedef-names as friends: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1520.pdf . The reason is that the Standard only supported elaborated-type-specifiers. It's easy to allow only those, and say if the entity declared as friend is not declared yet, it will be made a member of the surrounding namespace. But this means that if you want to use a template parameter, you would have to do (a class is required then for example)

friend class T;

But that brought additional problems, and it was figured not worth the gain. Now, the paper proposes to allow additional type specifiers to be given (so that this then allows use of template parameters and typedef-names).

The next C++ version (due to 2010) will be able to do it.

See this updated proposal to the standard: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1791.pdf . It will not allow only typedef names, but also template parameters to be used as the type declared as friend.

OTHER TIPS

AFAIK, In C++ typedef does not create a full-fledged synonyms when used in conjuction with classes. In other words, it's not like a macro.

Among the restrictions is that the synonym cannot appear after a class or struct prefix, or be used as a destructor or constructor name. You also cannot subclass the synonym. I would bet that is also means you can't friend it.

I tried in the VC++ 8.0 the code:

...
class C
{
public:
  friend class A;       
  friend X;             
  friend B::SUPERCLASS; 
};
...

It is compiled without errors.

I am not aware whether it MS specific or not.

A typedef defines a type. Friend decls declare friend classes or functions (substantially scopes), which then have "access" to the non public area of the declaring class...

Primitives, i.E. a float or an int* don't define a scope with code etc., they don't "use" the class anyway.

Don't forget, you can also "pack" call conventions, alignment attribs and other compiler specific stuff in a typedef, i.e. multiple vector TYPES implemented by the same class but with distinct alignment attribs. => A type is not a class, but vice versa.

IMHO, declaring a friend typedef can be useful, but when "class typedefs" from anywhere can be set as friend, the friendships can become extremely incomprehensible and therefore error-prone, especially where templates are used excessively.

Invalidating a single typedef can mess up the whole project due to widespread dependencies. Template friends and the 0x template typedefs are useful, but don't relax the rules of a friend declaration.

I don't know of any proposal concerning friend typedefs.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top