I am having a compiler error implementing operator<< on a C template class. Here is the code:
#pragma once
#include <iostream>
using namespace std;
//a template class to process a pair of "things"
template <typename T>
class Pair
{
private:
T first;
T second;
public:
Pair();
Pair(T, T);
friend ostream& operator<<(ostream&, Pair); //also tried Pair<T>
};
template <typename T>
Pair<T>::Pair()
{ }
template <typename T>
Pair<T>::Pair(T one, T two)
{
first = one;
second = two;
}
template <typename T>
ostream& operator<<(ostream& out, Pair<T> other)
{
out << "{ " << other.first << " and " << other.second << " }";
return out;
}
//test code
int main(){
Pair<string> words("red", "apple");
cout << "words is " << words << endl;
}
I am getting linker 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 Pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@V?$Pair@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@@@Z) referenced in function _main
CodePudding user response:
I found the mistake in class definition.
template <typename T>
friend ostream& operator<<(ostream&, Pair<T>);
I always forget that!
CodePudding user response:
The error message means that you declared a non-template friend function but does not define it for the template argument std::string
of the class template Pair
.
To avoid defining the function for different template arguments of the class template Pair
you should define it within the class definition. In this case the compiler itself will define the function for various template arguments of the class template Pair
when such a non-template friend function will be required.
The function can be declared and defined as it is shown in the demonstration program below.
Here is the demonstration program
#include <iostream>
#include <string>
template <typename T>
class Pair
{
private:
T first;
T second;
public:
Pair();
Pair( const T &, const T & );
friend std::ostream & operator <<( std::ostream &out, const Pair<T> &other )
{
return out << "{ " << other.first << " and " << other.second << " }";
}
};
template <typename T>
Pair<T>::Pair() : first(), second()
{ }
template <typename T>
Pair<T>::Pair( const T &one, const T &two ) : first( one ), second( two )
{
}
int main()
{
Pair<std::string> p( "first", "second" );
std::cout << p << '\n';
std::cout << Pair<int>() << '\n';
}
The program output is
{ first and second }
{ 0 and 0 }