Jump to content
  • Advertisement
Sign in to follow this  
coordz

C++ template class and template friend function

This topic is 3965 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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(....);
}

// or

template <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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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 ;)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!