Click here to Skip to main content
15,921,905 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
XML
#include "stdafx.h"
#include <iostream>
using namespace std;
#include <string>


template<class T>
class students
{
    friend void shows(students<T> &);

private:
    T name;
    void ShowInfo();

public:
        students(T x)
    {
        name=x;
    }
};

template<class T>
 void shows(students<T> &stu)
{
    cout<<stu.name;
}


int _tmain(int argc, _TCHAR* argv[])
{

    students <int>  mat(10);
    shows(mat);

    return 0;
}



Im getting this error:
Error 1 error LNK2019: unresolved external symbol "void __cdecl shows(class students<int> &)" (?shows@@YAXAAV?$students@H@@@Z) referenced in function _wmain
Posted

I don't think the friend-ness is the issue here although template friends are buggy to some extent in all versions of Visual Studio before 2012 as far as I can tell.
The problem seems to be that the compiler is 'probably' not generating code for the shows template function because it doesn't think it's being called instead it's looking for a function with a different signature which has not been written, trying to import it from the available libraries and failing.
I would try removing the friend declaration and doing something like this:

template< class T >
void shows( T& stu )
{
cout << stu.name;
}

int _tmain( int arg, _TCHAR* argv[] )
{
students< int > mat(10);
shows< students >( mat );

return 0;
}

This should then give you the error saying you can't access a private member of students. Then you can put the friend declaration back in based on the function signature it shows you in the error message.

templates are great for stretching the brain. good luck.
 
Share this answer
 
Comments
missak boyajian 30-Jan-13 11:54am    
I knew there was something with the compiler. I even copy pasted a code from http://www.cplusplus.com/forum/beginner/49509/ it gave the same error.

But I didn't understand your solution. How shows< students >( mat ) supposed to work?
Templates are great to kill my brain :)
Matthew Faithfull 30-Jan-13 12:03pm    
The idea of shows<students>(mat) is that its a request for an explicit instantiation of the shows template function. In English its a request to the compiler, with all the types filled in, to go generate a real function from the template. The thing to remember is that a template doesn't generate any code just because the compiler see it. Code only gets generated when the compiler finds the template being used later on. Then it tries fill in the template parameters and make 'real' code that can be called. If it doesn't recognize the template function you're refering to at the point where you make the call as 'one I declared as a template earlier' then it just assumes you're refering to a function from some library that will get linked in later, the function template goes unused and everyone has a bad day :-(
missak boyajian 30-Jan-13 12:15pm    
Thanks for help.Also I found a solution I put in place T
template < class u >
friend void shows( students < u > &);
An interesting question: C++ and friendship...

Here is the complete code:

C++
#include "stdafx.h"
#include <iostream>
using namespace std;

template<class T>
class students
{
public:
    friend void shows(T&);
    T name;
    void ShowInfo();
public:
    students(T x)
    {
        name=x;
    }
};

template<class T>
void shows(students<T> &stu)
{
    cout << stu.name << endl;
}

int _tmain(int argc, _TCHAR* argv[])
{

    students<int> mat(10);
    shows(mat);

    return 0;
}


It was also the privateness which made problems.

Best regards
 
Share this answer
 
v2
Comments
Matthew Faithfull 31-Jan-13 5:47am    
If everything in students< int > is public then you do not need the friend declaration. friend is meant to give specific classes or functions access to private functions and data. The tricky thing is here is specifying your friend declaration correctly. void shows(T&) is not the same function as template< class T > void shows( students<T>& ).

What compilation error message do you get exactly if you comment out the friend line and make T name a private member?
sja63 31-Jan-13 6:08am    
1> friend.cpp
1>c:\friend\friend.cpp(26): error C2248: "students<t>::name": Kein Zugriff auf private Member, dessen Deklaration in der students<t>-Klasse erfolgte.
1> with
1> [
1> T=int
1> ]
1> c:\friend\friend.cpp(14): Siehe Deklaration von 'students<t>::name'
1> with
1> [
1> T=int
1> ]
1> c:\friend\friend.cpp(33): Siehe Verweis auf die Instanziierung der gerade kompilierten Funktions-template "void shows<int>(students<t> &)".
1> with
1> [
1> T=int
1> ]
1>
1>Fehler beim Erstellen
1>
1>Verstrichene Zeit 00:00:00.74
========== Erstellen: 0 erfolgreich, Fehler bei 1, 0 aktuell, 0 übersprungen ==========
sja63 31-Jan-13 6:10am    
One can replace the line
friend void shows(T&);
by
void shows(T&);

So the friend declaration is for what?

I am confused
OK, that's what I thought although I don't often get error messages in German :-)

friend A

inside class S means: 'grant A access to the private members of S'

The problem is that you have said 'grant Z access to private members of S' and then tried to access private members of S from A

try changing your friend declaration to

friend template<> void shows( T& );

unfortunately this depends on your exact compiler version. In some it might have to be:

friend template void shows( T& );
friend template void shows< int >( students< int >& );

or even

friend template void shows<>( T& );

and in some it will not work however you write it. :-(

This I'm afraid is the confused state of C++ compilers when it comes to combining templates with friends.
Be gald you're not trying to export any of this on the interface of a shared library or it all gets much worse.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900