operator << friend功能和模板

use*_*001 6 c++ templates overloading operators friend

这是我的代码:

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;
}
Run Code Online (Sandbox Code Playgroud)

main.cpp中

#include "mov.h"

int main() {
    Movie<int> movie1(1);

    std::cout << movie1 << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我尝试编译此代码,我得到错误:

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
Run Code Online (Sandbox Code Playgroud)

如果我像这样内联代码,那就没关系:

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;
};
Run Code Online (Sandbox Code Playgroud)

如果我想分离定义和声明,我该怎么办?

谢谢.

Igo*_*nik 6

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;
}
Run Code Online (Sandbox Code Playgroud)

在您的原始代码中,您将成为非模板函数,恰好将其Movie<>作为参数进行正确的实例化.因此,每次Movie<T>实例化时,都会operator<<在封闭的命名空间范围内声明(但未定义)相应的非模板.friend声明这种方式很奇怪.

此外,您声明并定义一个名为的函数模板operator<<(它不是任何实例化的朋友Movie).但是,重载决策更喜欢非模板,其他条件相同.