Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C++
#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 &)" (?shows@@YAXAAV?$students@H@@@Z) referenced in function _wmain
Posted 30-Jan-13 5:19am
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

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.
  Permalink  
Comments
missak boyajian at 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 at 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 at 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 > &);
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

An interesting question: C++ and friendship...
 
Here is the complete code:
 
#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
  Permalink  
v2
Comments
Matthew Faithfull at 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?
Member 9586495 at 31-Jan-13 6:08am
   
1> friend.cpp
1>c:\friend\friend.cpp(26): error C2248: "students::name": Kein Zugriff auf private Member, dessen Deklaration in der students-Klasse erfolgte.
1> with
1> [
1> T=int
1> ]
1> c:\friend\friend.cpp(14): Siehe Deklaration von 'students::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(students &)".
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 ==========
Member 9586495 at 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
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 3

OK, that's what I thought although I don't often get error messages in German Smile | :)
 
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. Frown | :-(
 
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.
  Permalink  

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

  Print Answers RSS
0 OriginalGriff 330
1 Nirav Prabtani 242
2 Richard Deeming 240
3 CHill60 170
4 _Amy 145
0 OriginalGriff 8,104
1 Sergey Alexandrovich Kryukov 7,045
2 Maciej Los 4,039
3 Peter Leow 3,738
4 CHill60 2,912


Advertise | Privacy | Mobile
Web02 | 2.8.140721.1 | Last Updated 31 Jan 2013
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100