Topic: friends of templates accessing types


Author: James Kuyper <kuyper@wizard.net>
Date: 1998/06/19
Raw View
John M. Vreeland wrote:
...
> of?  Why should "typename" or "struct" or "class" be required at all?

Because "typename" allows the compiler to assume that a given class
member is a typedef, rather than a function or a variable. As a result,
certain syntax errors can be detected in the template itself, without
any need to instantiate it. Making "typename" mandatory where relevant
simplifies the instantiation process, since there is guaranteed to be no
need to re-do those syntax checks.
---
[ 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: "John M. Vreeland" <jmvree@infi.net>
Date: 1998/06/18
Raw View
Yes, I tried adding the keyword "typename", but it accomplished nothing.  As
I was writing this it occured to me to try "struct" and that worked just
fine.  Since the compiler was giving me an accessibility error it never
occured to me that it was confusing a type with an identifier.  I had assumed
that since the entire class was specified in this file and that I was
referring to it explicitly that there would be no such confusion.  Stroustrop
seems to give some equivalent examples (C++ programming language, 3rd ed.,
page 857).  Or, before I take the obscurantists over at Borland/Inprise to
task, is there some source of confusion in this example that I am not aware
of?  Why should "typename" or "struct" or "class" be required at all?

My thanks to all
Marc Girod wrote:

> >>>>> "JV" == John M Vreeland <jmvree@infi.net> writes:
>
> JV> I asked this one before, improperly, so I'll try again.
> JV> Shouldn't template friends of templates have access to private types,
> JV> and not just private data?
>
> Add one "typename" to your code, and HP aCC v 1.12 compiles it fine.
> After that, I fully agree with you.
>
> JV> //forward declaration for friend
> JV> template <class T> class B;
>
> JV> template <class T>
> JV> class A {
> JV> public: friend class B<T>;
> JV> private: struct PrivateStruct{T * data;};
> JV> };
>
> JV> template <class T>
> JV> class B {
> JV> private: A<T>::PrivateStruct localCopy;
>     private: typename A<T>::PrivateStruct localCopy;
> JV> };
>
> JV> int main()
> JV> {
> JV>    A<int> a;
> JV>    B<int> b;  //A<int>PrivateStruct is not accessible.
> JV> }
---
[ 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: "John M. Vreeland" <jmvree@infi.net>
Date: 1998/06/15
Raw View
Checking the standard, (14.5.3 temp.friend) it seems that compilers are
required to allow friends of template classes and vice-versa, but not both at
the same time.  Am I reading this correctly?  I am astonished if so.
Container classes are one of the few justifiable places for using friends,
and both the iterator and container are likely to be templates.

In any event I found a reasonable solution to the dillema.  I modified the
original code to declare the private type definition in the public section of
the class.  It's only a type, after all, not data.  Still it seems like it
should be accessible to friends.

Here is a slightly simpler example that fails to compile under Borland 5.0x

//forward declaration for friend
template <class T> class B;

template <class T>
class A {
public: friend class B<T>;
private: typedef int Aint;  //if this were public it would compile
};

template <class T>
class B {
private: typedef A<T>::Aint Bint; //compiles okay, just won't instantiate
};

int main()
{
A<int> a;
B<int> b;  //A<int>::Aint is not accessible.
}




[ 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: "John M. Vreeland" <jmvree@infi.net>
Date: 1998/06/14
Raw View
I asked this one before, improperly, so I'll try again.
Shouldn't template friends of templates have access to private types,
and not just private data?

I have some code that compiles just fine in my version of GNU++, but
fails to instantiate under Borland 5.0x.  It seems like it SHOULD
compile, especially since it will if I remove the template
specifications, but otherwise I get an access violation.  At least in
the new compiler it shows up in main where it occurs and not in the
header, which was hard to trace.

The fact that it compiles fine if I remove the templates is really
indicating a compiler bug to me.

//forward declaration for friend
template <class T> class B;

template <class T>
class A {
public: friend class B<T>;
private: struct PrivateStruct{T * data;};
};

template <class T>
class B {
private: A<T>::PrivateStruct localCopy;
};

int main()
{
   A<int> a;
   B<int> b;  //A<int>PrivateStruct is not accessible.
}
---
[ 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              ]