template<class T>
class test
{
vector<int> v;
public:
test()
:v(10, 1)
{}
friend void show_test(test<T>&);
};
template<class T>
void show_test(test<T>& t)//friend function of test
{
for(unsigned short i = 0; i < t.v.size(); ++i)
cout << t.v << " ";
cout << endl;
}
void demo_test()
{
test<int> t;
show_test(t);
}
int main()
{
demo_test();
return 0;
}
friend function & template
I write some codes like this:
But the compiler always pops:
Linking...
cpptest.obj : error LNK2001: unresolved external symbol "void __cdecl show_test(class test<int> &)" (?show_test@@YAXAAV?$test@H@@@Z)
what's wrong here?
You need to tell the compiler that the friend function is a template in the declaration. You can do this by appending empty <> brackets to the name like this:
friend void show_test<>(test<T>&);
The problem lies in that friend templates require explicit statement of the fact they are templates. Hence the following (with some additional comments :) )
// Don't forget to include headers so we can reproduce the example!#include <vector>#include <iostream>using namespace std; // Blehtemplate<class T>class test{ vector<int> v;public: test() : v(10,1) {} // Note the additional syntax making the template statement explicit template <typename T> friend void show_test(test<T>&);};// Firstly this function shouldn't be a free function; it should be a "Report" member function of testtemplate<class T>void show_test(test<T>& t){ // Firstly tidying up the loop the way you wrote it // How do you know "i" is an unsigned short? for(unsigned short i = 0; i < t.v.size(); ++i) // We are assuming v will be a vector<int>, what if you change the test class and forget to change this? // Take advantage of the nested typedefs // Note that this is a good illustration of why friendship is the strongest relationship classes can have to each other: // for(vector<int>::size_type i = 0; i < t.v.size(); ++i) cout << t.v << " "; cout << endl; // And this is how I would do it, which makes life a lot easier! // However, we are still using the int template variable explicitly - friendship, bleh copy(t.v.begin(), t.v.end(), ostream_iterator<int>(cout, " ")); cout << endl;}int main(){ test<int> t; show_test(t); // So sue me, I used system("pause") system("pause"); return 0;}// The class we could have had!// I am assuming here that the container should have been of T and not int; otherwise why template?template<class T>class test2{ vector<T> v;public: test2() : v(10,1) {} void Report() { copy(v.begin(), v.end(), ostream_iterator<T>(cout, " ")); cout << endl; }};
Hollower, I am afraid that you suggestion doesn't work. Maybe it's compiler issue(My compiler is vc2005). Anyway, thanks a lot!
Also, special thanks to you, JimPrice! Especially your additional comments. Now everything is done. :)
Also, special thanks to you, JimPrice! Especially your additional comments. Now everything is done. :)
Quote:I also found another solution which uses the template <class ...> variant here
The two 'solutions' are identicle. In the context of a template class and typename both mean the same thing, that the template paramater is a type :). (exception: template template paramaters)
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement