#include <iostream>
using namespace std;
template <typename T>
class test
{
T y;
public:
test(T k) : y(k) {}
friend int a(T& x);
};
template <typename T>
int a(T& x)
{
cout << x.y;
return 9;
}
template <>
class test<int>
{
int y;
public:
test(int k) : y(k) {}
friend int a(int& x);
};
template <>
int a<int>(int& x)
{
cout << "4";
return 0;
}
int main(int argc, char* argv[])
{
test<int> z(3);
a(z);
return 0;
}
I want to make a friend class of test class (in a real case, it was a operator<< of ofstream). But I have no idea how to define template friend function of specialized class.
Besides, the code above shows this compile error message;
error C2248: ‘test::y’ : cannot access private member declared in
class ‘test’
Question added;
Aaron McDaid works fine for me, but I was trying to overload operator<< of ofstream class.
friend ofstream& operator<< <test<int>> (ofstream& os, const test<int>& t);
I added code above to test class and
template<>
ofstream& operator<< <test<int> > (ofstream& os, const test<int>& t)
{
os << t.y;
return os;
}
used code above. But it looks like I cannot use os << t.y (which is int) I don’t understand why this happens. The error message is
error C2027: use of undefined type ‘std::basic_ofstream<_Elem,_Traits>’
(Update: Here’s a fully tested version on http://ideone.com/3KGU4. For the Additional question, see http://ideone.com/w0dLo)
There is a difference between ordinary overloaded functions and template functions. For example, without any reference to templates a developer can declare:
Alternatively, a developer could use templates,
A major difference between them is that with ordinary functions, you must decide on a fixed set of allowed parameters in advance, and you must provide an implementation for each one. With templates, you can be more flexible.
Later in your program, it is clear that you want
ato be a template function, not simply an (overloaded) ordinary function. But when the compiler first sees mention ofa(around line 10), it looks like it is declaring an ordinary function. To resolve this, you must take two steps. You must declare as soon as possible thatais a template function, so your first line should be:Then you must declare the relevant friendship. If
Tisint, thenatakes a parameter oftest<int>&, notint&. Therefore the two friend lines should be replaced with:and the specialization of
ashould be:The Additional Question
Use
ostreaminstead ofofstream(or else include#include <fstream>if you will output only to files and not tocout). In my answer,operator <<is not a template, but is a normal overloaded function. I’m not sure it’s possible to haveoperator<<as a template. Also, I defined the operator at the place where it is declared and declared as a friend. To be honest, I think there are other, maybe better, ways but this worked for me.