Then the compiler substitutes int for TT and generates the following class definition:
class HasFriendT
{
...
friend void counts
friend void report<>(HasFriendT
};
One specialization is based on TT, which becomes int, and the other is based on HasFriendT, which becomes HasFriendT
The third requirement the program must meet is to provide template definitions for the friends. Listing 14.23 illustrates these three aspects. Note that Listing 14.22 has one count() function that is a friend to all HasFriend classes, whereas Listing 14.23 has two count() functions, one of which is a friend to each of the instantiated class types. Because the count() function calls have no function parameter from which the compiler can deduce the desired specialization, these calls use the count
report
Listing 14.23. tmp2tmp.cpp
// tmp2tmp.cpp -- template friends to a template class
#include
using std::cout;
using std::endl;
// template prototypes
template
template
// template class
template
class HasFriendT
{
private:
TT item;
static int ct;
public:
HasFriendT(const TT & i) : item(i) {ct++;}
~HasFriendT() { ct--; }
friend void counts();
friend void report<>(HasFriendT &);
};
template
int HasFriendT
// template friend functions definitions
template
void counts()
{
cout << "template size: " << sizeof(HasFriendT
cout << "template counts(): " << HasFriendT
}
template
void report(T & hf)
{
cout << hf.item << endl;
}
int main()
{
counts
HasFriendT
HasFriendT
HasFriendT
report(hfi1); // generate report(HasFriendT
report(hfi2); // generate report(HasFriendT
report(hfdb); // generate report(HasFriendT
cout << "counts
counts
cout << "counts
counts
return 0;
}
Here is the output of the program in Listing 14.23:
template size: 4; template counts(): 0
10
20
10.5
counts
template size: 4; template counts(): 2
counts
template size: 8; template counts(): 1
As you can see, counts
Unbound Template Friend Functions to Template Classes
The bound template friend functions in the preceding section are template specializations of a template declared outside a class. An int class specialization gets an int function specialization, and so on. By declaring a template inside a class, you can create unbound friend functions for which every function specialization is a friend to every class specialization. For unbound friends, the friend template type parameters are different from the template class type parameters:
template
class ManyFriend
{
...
template
};
Listing 14.24 shows an example that uses an unbound friend. In it, the function call show2(hfi1, hfi2) gets matched to the following specialization:
void show2
(ManyFriend
Because it is a friend to all specializations of ManyFriend, this function has access to the item members of all specializations. But it only uses access to ManyFriend
Similarly, show2(hfd, hfi2) gets matched to this specialization:
void show2
(ManyFriend
It, too, is a friend to all ManyFriend specializations, and it uses its access to the item member of a ManyFriend
Listing 14.24. manyfrnd.cpp
// manyfrnd.cpp -- unbound template friend to a template class
#include
using std::cout;
using std::endl;
template
class ManyFriend
{
private:
T item;
public:
ManyFriend(const T & i) : item(i) {}
template
};
template
{
cout << c.item << ", " << d.item << endl;
}
int main()
{