Let's say I'm creating a class for a binary tree, BT
, and I have a class which describes an element of the tree, BE
, something like
template<class T> class BE { T *data; BE *l, *r; public: ... template<class U> friend class BT; }; template<class T> class BT { BE<T> *root; public: ... private: ... };
This appears to work; however I have questions about what's going on underneath.
I originally tried to declare the friend as
template<class T> friend class BT;
however it appears necessary to use U
(or something other than T
) here, why is this? Does it imply that any particular BT
is friend to any particular BE
class?
The IBM page on templates and friends has examples of different type of friend relationships for functions but not classes (and guessing a syntax hasn't converged on the solution yet). I would prefer to understand how to get the specifications correct for the type of friend relationship I wish to define.
The following example demonstrates these relationships: class B{ template<class V> friend int j(); } template<class S> g(); template<class T> class A { friend int e(); friend int f(T); friend int g<T>(); template<class U> friend int h(); };
A template friend declaration can name a member of a class template A, which can be either a member function or a member type (the type must use elaborated-type-specifier).
Class Template: We can define a template for a class. For example, a class template can be created for the array class that can accept the array of various types such as int array, float array or double array.
A friend function is a special function in C++ which in-spite of not being member function of a class has privilege to access private and protected data of a class. A friend function is a non member function or ordinary function of a class, which is declared as a friend using the keyword “friend” inside the class.
template<class T> class BE{ template<class T> friend class BT; };
Is not allowed because template parameters cannot shadow each other. Nested templates must have different template parameter names.
template<typename T> struct foo { template<typename U> friend class bar; };
This means that bar
is a friend of foo
regardless of bar
's template arguments. bar<char>
, bar<int>
, bar<float>
, and any other bar
would be friends of foo<char>
.
template<typename T> struct foo { friend class bar<T>; };
This means that bar
is a friend of foo
when bar
's template argument matches foo
's. Only bar<char>
would be a friend of foo<char>
.
In your case, friend class bar<T>;
should be sufficient.
In order to befriend another same-type struct:
#include <iostream> template<typename T_> struct Foo { // Without this next line source.value_ later would be inaccessible. template<typename> friend struct Foo; Foo(T_ value) : value_(value) {} template <typename AltT> void display(AltT &&source) const { std::cout << "My value is " << value_ << " and my friend's value is " << source.value_ << ".\n"; } protected: T_ value_; }; int main() { Foo<int> foo1(5); Foo<std::string> foo2("banana"); foo1.display(foo2); return 0; }
With the output as follows:
My value is 5 and my friend's value is banana.
In template<typename> friend struct Foo;
you shouldn't write T
after typename
/class
otherwise it will cause a template param shadowing error.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With