【问题标题】:operator << friend function and templates运算符 << 朋友函数和模板
【发布时间】:2014-10-07 11:27:30
【问题描述】:

这是我的代码:

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

我尝试编译这段代码,但我得到了错误:

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

如果我像这样尝试内联代码,没关系:

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

如果我想把定义和声明分开怎么办?

谢谢。

【问题讨论】:

  • FWIW,如果您将声明模板化或在定义中使用特定类型,它就可以工作。

标签: c++ templates operators overloading friend


【解决方案1】:
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;
}

在您的原始代码中,您与一个非模板函数成为朋友,该函数恰好将Movie&lt;&gt; 的正确实例化作为参数。因此,每次实例化 Movie&lt;T&gt; 时,都会在封闭的命名空间范围内声明(但未定义)相应的非模板 operator&lt;&lt;friend 声明这种方式很奇怪。

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

【讨论】:

  • +1 以获得快速正确的解决方案,但您应该解释原因。语境化...
  • 为什么不将operator&lt;&lt; 设为Movie 中的模板?
  • @0x499602D2:如果愿意在课堂上实现operator&lt;&lt;,则不必将其设为模板。 OP 实际上以这种方式工作 - 请参阅问题的“如果我像这样尝试内联代码,那没关系”部分。但他或她特别询问了如何使其与类外实现一起工作。
猜你喜欢
  • 1970-01-01
  • 2016-08-27
  • 1970-01-01
  • 2014-12-07
  • 2020-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多