为什么我在声明的函数上出现 link 错误?

Why I am getting link error on declared function?

考虑这个 class 示例。简化版。

#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;
}

我得到:

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@@@Z) referenced in function _main

谁能解释一下为什么?我想我已经实现了这个功能。

class定义里面的友元声明声明了一个non-template函数,那你后面再定义一个模板函数,它们不匹配。 non-template 函数在重载决策中是首选的,但它没有定义,所以你得到了 link 错误。

您可以在 class 定义中定义它,

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];
};

或者引用模板函数进行友元声明

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;
}