I have written the following code:
#include <iostream>
using namespace std;
template <class T>
class AA
{
T a;
public:
AA()
{
a = 7;
}
friend void print(const AA<T> & z);
};
template <class T>
void print(const AA<T> & z)
{
cout<<"Print: "<<z.a<<endl;
}
void main()
{
AA<int> a;
print<int>(a);
}
And getting the following error:
error C2248: 'AA<T>::a' : cannot access private member declared in class 'AA<T>'
1> with
1> [
1> T=int
1> ]
1> c:\users\narek\documents\visual studio 2008\projects\aaa\aaa\a.cpp(7) : see declaration of 'AA<T>::a'
1> with
1> [
1> T=int
1> ]
1> c:\users\narek\documents\visual studio 2008\projects\aaa\aaa\a.cpp(30) : see reference to function template instantiation 'void print<int>(const AA<T> &)' being compiled
1> with
1> [
1> T=int
1> ]
What’s wrong?
P.S. I am using Visual Studio 2008.
The problem is that when you do something like
and you instantiate
AAwith like thisthe friend declaration will be instantiated like
which is a non-template function! This means the compiler will not match the friend declaration with your
printfunction.The solution is basically to declare
printbeforeAAand explicitly tell the compiler that your friend declaration is talking about a template function. Like this:It is interesting to see what happens if you do not add the
<>in the friend declaration. You will get a linker error. Why? Well, because the compiler cannot match the friend declaration with your templateprintfunction, it will implicitly assume a function with prototypeexists. Since I didn’t explicitly provide a template parameter to the call to
print(which isn’t necessary because the compiler should be able to deduce this), the compiler will match this call with the function declared as friend. This function is nowhere implemented, hence the linker error.