C++ template class and template friend function

Started by
3 comments, last by coordz 16 years, 9 months ago
I've just been adding some code to a template class and have needed to use a friend function. Not a problem, works fine, but I came across something I didn't quite understand. In my code I did something like

template <class T> class myClass{
public:
  void someNormalMemberFunction(T a);

  template <class T> friend T myFriend(myClass<T> a);
}

template <class T> friend T myFriend(myClass<T> a){
  // do some stuff
  return(....);
}

and that works fine. I then came across a newsgroup posting suggesting the way to do friend functions of template classes was to do:

template <class T> class myClass{
public:
  void someNormalMemberFunction(T a);

  template <class T2> friend T2 myFriend(myClass<T2> a);
}

template <class T2> friend T2 myFriend(myClass<T2> a){
  // do some stuff
  return(....);
}

Now as far as I can see, the definition of myFriend() is identical in both cases as T and T2 are just a type label and could be called anything I want. In the declaration of myClass, T and T2 are different: T is the type of the template class and T2 is a different type. So what's the difference? I've tried both versions and they work as expected in my code. Which one should I be using? TIA
Advertisement
I might be wrong, but I think that in the first version only myFriend<int>, for example, is a friend of MyClass<int>, while in the second version it has an infinite number of friends.
For each type T, do you want myClass<T> to befriend all possible template instantiations of myFriend, or just myFriend<T>?

I believe that in both of the examples you showed that the former is happening. Re-using the name T there is really rather strange.

I believe you want one of the following, which are different:

template <class T> class myClass{public:  void someNormalMemberFunction(T a);  template <class U> friend U myFriend(myClass<U> a);}template <class U> friend U myFriend(myClass<U> a){  // do some stuff  return(....);}// ortemplate <class T> class myClass{public:  void someNormalMemberFunction(T a);  friend T myFriend<T>(myClass<T> a);}template <class T> friend T myFriend(myClass<T> a){  // do some stuff  return(....);}


On the first situation, myFriend<U>() can access the private guts of myClass<T> for any types U and T (which can of course be different).

In the second situation, myFriend<T> can only access the private guts of myClass<T>.

Edd
Given this:
typedef MyClass<int> IntClass;typedef MyClass<float> FloatClass;
First example generates this code:
class IntClass{public:  void someNormalMemberFunction(int a);  friend int myFriend(IntClass a);}class FloatClass{public:  void someNormalMemberFunction(floata);  friend float myFriend(FloatClass a);}
You cannot assign one to another, and neither can access the other's private members.

For second case, the folowing code gets generated:
class IntClass{public:  void someNormalMemberFunction(int a);  friend int myFriend(IntClass a);  friend float myFriend(FloatClass a);}class FloatClass{public:  void someNormalMemberFunction(float a);  friend int myFriend(IntClass a);  friend float myFriend(FloatClass a);}
Both have access to each other's private members, and they can be cross-assigned.

This is same as rebind<> concept in STL allocators, which allow assignment between containers with different allocators.
I now understand the difference between the two but I'm still unsure of when to use them, especially the second.

Quote:Both have access to each other's private members, and they can be cross-assigned.

This is same as rebind<> concept in STL allocators, which allow assignment between containers with different allocators.


I'm not familiar with the STL or what the cross assignment is. Surely IntClass can never be assigned to FloatClass?

For my app the single friend usage (i.e. using the same T all the way through) is what I wanted so I'm now in the realms of learning something useful I could apply later on ;)

This topic is closed to new replies.

Advertisement