C++模板类重载<<运算符提示不匹配模板声明如何解决
问题原因及修复方案
报错是三个模板类友元运算符重载的常见误区导致的:
- 没有提前声明模板化的
operator<<,类内的友元声明找不到匹配的模板定义 - 模板函数的实现放在了.cpp文件,编译期其他编译单元无法看到模板实现完成实例化,后续还会触发链接错误
- 缺少
std::命名空间前缀、类定义末尾缺分号、运算符参数未加const修饰等语法疏漏
推荐实现方式(头文件内完成)
模板类关联的模板函数默认需要把实现放在头文件中,才能保证编译期可以完成对应类型的实例化,正确代码如下:
// foo.h 头文件内容 #include <iostream> // 第一步:前置声明foo类模板 template <class T> class foo; // 第二步:前置声明要作为友元的operator<<模板 template <class T> std::ostream& operator<<(std::ostream& output, const foo<T>& F); template <class T> class foo { // 友元声明,指定匹配上面的模板实例 friend std::ostream& operator<< <T>(std::ostream& output, const foo<T>& F); // 你的类成员定义 private: T value; }; // 第三步:模板函数实现放在头文件中 template <class T> std::ostream& operator<<(std::ostream& output, const foo<T>& F) { // 可以直接访问foo<T>的私有成员 output << "whatever: " << F.value; return output; }
如果希望简化写法,也可以直接在类内定义operator<<,省略前置声明步骤:
template <class T> class foo { friend std::ostream& operator<<(std::ostream& output, const foo<T>& F) { output << "whatever"; return output; } // 类其他成员定义 };
特殊场景:模板实现放在.cpp文件
如果你一定要把实现放在.cpp文件中,需要提前显式实例化所有会用到的模板参数类型:
// foo.cpp 文件内容 #include "foo.h" template <class T> std::ostream& operator<<(std::ostream& output, const foo<T>& F) { output << "whatever: " << F.value; return output; } // 末尾显式实例化所有要用到的类型,比如用到foo<int>、foo<double>就加以下两行 template std::ostream& operator<<<int>(std::ostream& output, const foo<int>& F); template std::ostream& operator<<<double>(std::ostream& output, const foo<double>& F); template class foo<int>; template class foo<double>;
内容的提问来源于stack exchange,提问作者blackarrow
相关产品推荐
相关产品推荐

