2

Consider this class example. Simplified version.

#include <iostream>
#include <vector>
#include <iomanip>

using std::setw;
using std::ostream;
using std::istream;

template<class T=int, int size=10>
class Array
{
     friend istream& operator>>(istream&, Array<T,size>&);
public:
private:
     T arr[size];
};

template<class T, int size>
istream& operator>>(istream& input, Array<T,size> &a)
{
     for(int i=0; i<size;++i)
     {
          input>>a.arr[i];
     }
     return input;
}

int main()
{
     Array<int> x;
     std::cin>>x;
}

I am getting:

1>main.obj : error LNK2019: unresolved external symbol "class std::basic_istream<char,struct std::char_traits<char> > & __cdecl operator>>(class std::basic_istream<char,struct std::char_traits<char> > &,class Array<int,10> &)" (??5@YAAAV?$basic_istream@DU?$char_traits@D@std@@@std@@AAV01@AAV?$Array@H$09@@@Z) referenced in function _main

Can anyone explain why? I think I have implemented the function.

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
Eduard Rostomyan
  • 7,050
  • 2
  • 37
  • 76
  • 2
    [Useful warning messages](https://tio.run/##fZDJasQwEETv/RUNAWMzTphcvQjyD76FHBRZGRpsWUjyZMPf7mjxjCcQooMEr6urCgmt709CrOsdKTHMvcSGJuuM5CODnZ2lcJO5JTSNXJFmALMldULr@qqy0r3Xt2Cz@sXowsDJUQ/cyUYM3FrsWlKuRH@hpS/ZPh4ZpMmTMfwTvgHDeTMkVY@bTYaTloaHdiy/sDJtNF0ZnVhW1KDn14FEBdrQ2WdWyaxDbsxzEL3UsPzRae/D4L9IL9Oz24PjBma8uNaeTB6sqD3WSE2Y14cDFWm6ieKJTozxh1CNfK9Il/QY6WajksY3BgieIyeVX5NSBc8ZfmzL8eMFKcY8Wdb1Bw). – user202729 Apr 05 '18 at 14:09
  • (this time GCC produces better warning messages than MSVC) – user202729 Apr 05 '18 at 14:13

1 Answers1

3

The friend declaration inside class definition declares a non-template function, then you define a template function later, they don't match. The non-template function is perferred in overload resolution, but it's not defined so you got the link error.

You could define it inside the class definition,

template<class T=int, int size=10>
class Array
{
     friend istream& operator>>(istream&, Array<T,size>&)
     {
         for(int i=0; i<size;++i)
         {
             input>>a.arr[i];
         }
         return input;
     }
public:
private:
     T arr[size];
};

Or make the friend declaration refering to the template function.

template<class T=int, int size=10>
class Array;

template<class T, int size>
istream& operator>>(istream& input, Array<T,size> &a);

template<class T, int size>
class Array
{
     friend istream& operator>> <>(istream&, Array<T,size>&);
public:
private:
     T arr[size];
};

template<class T, int size>
istream& operator>>(istream& input, Array<T,size> &a)
{
     for(int i=0; i<size;++i)
     {
          input>>a.arr[i];
     }
     return input;
}
songyuanyao
  • 169,198
  • 16
  • 310
  • 405