This is my code:
mov.h
#include <iostream>
template< class T>
class Movie {
public:
Movie(T in) {
a = in;
}
friend std::ostream& operator<<(std::ostream& os, const Movie<T>& movie);
private:
T a;
};
template<class T>
std::ostream& operator<<(std::ostream& os, const Movie<T>& movie) {
return os;
}
main.cpp
#include "mov.h"
int main() {
Movie<int> movie1(1);
std::cout << movie1 << std::endl;
return 0;
}
I try to compile this code, and I get the error:
Error 1 error LNK2019: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class Movie<int> const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABV?$Movie@H@@@Z) referenced in function _main c:\Users\Adi\documents\visual studio 2013\Projects\bdika01\bdika01\main.obj bdika01
Error 2 error LNK1120: 1 unresolved externals c:\users\adi\documents\visual studio 2013\Projects\bdika01\Debug\bdika01.exe 1 1 bdika01
If I try the code inline like this it's okay:
mov.h
#include <iostream>
template<class T>
class Movie {
public:
Movie(T in) {
a = in;
}
friend std::ostream& operator<<(std::ostream& os, const Movie<T>& movie){
return os;
}
private:
T a;
};
What can I do if I want to separate the defination and declaration?
Thanks.
Function templates. Function templates are special functions that can operate with generic types. This allows us to create a function template whose functionality can be adapted to more than one type or class without repeating the entire code for each type. In C++ this can be achieved using template parameters.
Many-to-one: All instantiations of a template function may be friends to a regular non-template class. One-to-one: A template function instantiated with one set of template arguments may be a friend to one template class instantiated with the same set of template arguments.
Templates are powerful features of C++ which allows us to write generic programs. We can create a single function to work with different data types by using a template.
Here in the above program, operator function is implemented outside of class scope by declaring that function as the friend function.
template <typename T> class Movie;
template<class T>
std::ostream& operator<<(std::ostream& os, const Movie<T>& movie);
template< class T>
class Movie {
friend std::ostream& operator<< <T>(std::ostream& os, const Movie<T>& movie);
};
template<class T>
std::ostream& operator<<(std::ostream& os, const Movie<T>& movie){
return os;
}
In your original code, you befriend a non-template function that just happens to take the right instantiation of Movie<>
as a parameter. So, every time a Movie<T>
is instantiated, a corresponding non-template operator<<
is declared (but not defined) in the enclosing namespace scope. friend
declarations are strange this way.
In addition, you declare and define a function template named operator<<
(which is not a friend of any instantiation of Movie
). However, overload resolution prefers non-templates, other things equal.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With