friends of template classes

I'm stuck trying to call a function which is a friend of a template class. I get a compilation error (in visual studio 2010 express: unresolved external symbol "void __cdecl f(class MyClass<int> &)" (?f@@YAXAAV?$MyClass@H@@@Z) ) - though if I comment out line 27 which actually calls the function the thing compiles and runs fine.

I've compared it to the example at msdn (http://msdn.microsoft.com/en-us/library/f1b2td24%28v=vs.80%29.aspx) and can't see any difference in syntax. Sure I must be doing something simple wrong but have been fiddling for hours and can't figure it.

Any pointers?

Thanks


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
using namespace std;

template <class T>
class MyClass
{
	friend void f(MyClass<T>&);
public:
	T getValue(){return value;}
	void setValue(T v){value=v;}
private:
	T value;
};

template<class T>
void f(MyClass<T>& c)
{
	cout<<"Function called"<<endl;
	cout<<c.getValue()<<endl;
}


int main()
{
	MyClass<int> object;
	object.setValue(6);
	f(object);
}
If you change line 7 to
1
2
template <class U>
friend void f(MyClass<U>&);
it works. Same is done in that example you posted a link to. I guess putting a friend in a template class and giving it a template argument is not enough for compiler to figure out that f is a template function.
Note that you could alternatively put the definition of the friend function on line 7. That way there are no problems either.
Thanks that's brilliant - knew it must be something simple...

And I've now learned that you can define a friend function in the class header : )

Cheers!
You also learned that C++ will do silly things for you without any good reason and without telling you how to fix them..
However the behaviour is not the same.
1
2
template <class U>
friend void f(MyClass<U>&);
is making a lot of friends. f<string> will be friend of MyClass<int>
http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Ffriends_and_templates.htm

For a one to one correspondence
1
2
3
4
5
6
7
8
//forward declaration
template <class T> class MyClass;
template <class T> void f(MyClass<T>&);

template <class T>
class MyClass
	{
		friend void f<>(MyClass<T>&); //'void f(MyClass<T>&)' declares a non-template function 
Topic archived. No new replies allowed.