【问题标题】:C++ templates and friends, linker errorC++ 模板和朋友,链接器错误
【发布时间】:2024-06-19 01:30:02
【问题描述】:

为什么下面的代码无法编译(链接器错误,无法解析的外部符号,class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class cClass<int> const &)" (??6@YAAEAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AEAV01@AEBV?$cClass@H@@@Z)

#include <iostream>

template <class Type> class Class{
    public:
        friend std::ostream& operator<<(std::ostream& Stream, const Class& Op);
};

template <class Type> std::ostream& operator<<(std::ostream& Stream, const Class<Type>& Op){
    return(Stream);
}

int main(){
    Class<int> A;

    std::cout << A;

    return(0);
}

【问题讨论】:

  • 查找友元函数的语义。您还必须将类中的友元函数声明为模板。

标签: c++ c++11


【解决方案1】:

这一行:

friend std::ostream& operator<<(std::ostream& Stream, const Class& Op);

应该是:

template <class T> friend std::ostream& operator<<(std::ostream& Stream, const Class<T>& Op);

【讨论】:

  • 谢谢,它有效。但是如果我想在不同的文件中有接口和实现呢?
  • here 所述:模板的定义必须在隐式实例化时可见,这就是模板库通常在标头中提供所有模板定义的原因
  • @Mario 您可以在文件末尾、标题保护#endif 之前#include ".cpp"`,并将模板实现移动到您的 cpp 文件中
  • @Varaquilex 包含 .cpp 文件远非一个好习惯。
  • 有关模板的更多信息,另请参阅here