朋友声明声明一个非模板函数

我有一个基类类似于下面的代码。 我试图超载<<用于cout。 但是,g ++说:

base.h:24: warning: friend declaration 'std::ostream& operator<<(std::ostream&, Base<T>*)' declares a non-template function base.h:24: warning: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here) -Wno-non-template-friend disables this warning 

我已经尝试在类声明/原型之后添加<>。 但是,然后我得到它does not match any template declaration 。 我一直在试图让运营商的定义完全模板化(我想),但我只能得到它与以下代码,手动实例化运营商。

base.h

 template <typename T> class Base { public: friend ostream& operator << (ostream &out, Base<T> *e); }; 

base.cpp

 ostream& operator<< (ostream &out, Base<int> *e) { out << e->data; return out; } 

我想只在头文件base.h中有这个或者类似的东西:

 template <typename T> class Base { public: friend ostream& operator << (ostream &out, Base<T> *e); }; template <typename T> ostream& operator<< (ostream &out, Base<T> *e) { out << e->data; return out; } 

我已经在网上看过其他地方,把<<和()之间的<>放在原型中应该解决这个问题,但是并没有。 我可以把这个到一个单一的function模板?

这听起来像你想改变:

 friend ostream& operator << (ostream& out, const Base<T>& e); 

至:

 template<class T> friend ostream& operator << (ostream& out, const Base<T>& e); 

Gcc正确地警告你。 尽pipe它是外观(它需要Base参数),但它不是一个函数模板。

你的类定义有一个非模板声明的友元函数(没有模板),但稍后的朋友函数定义是一个函数模板(即以模板开始)。

另外你的运营商<<需要一个基地*。 这是不正确的。 它应该是基本常量&保留它的内置语义

可能你正在看如下的东西:

 template <typename T> class Base { public: friend ostream& operator << (ostream &out, Base<T> const &e){ return out; }; }; int main(){ Base<int> b; cout << b; } 

如果你想完全模板化,那么这可能是你想要的。 但是我不确定这个比以前有多大用处。 由于查找涉及到ADL,因此您将永远无法解决任何T不等于U的条件(只要该调用来自与此类无关的上下文,例如来自“main”函数)

 template <typename T> class Base { public: template<class U> friend ostream& operator << (ostream &out, Base<U> const &e){ return out; }; }; int main(){ Base<int> b; cout << b; } 

可能你要找的是:

 template <typename T> class Base; template <typename T> ostream& operator<< (ostream &, const Base<T>&); template <typename T> class Base { public: template<> friend ostream& operator << <T>(ostream &, const Base<T> &); }; template <typename T> ostream& operator<< ( ostream &out, const Base<T>& e ) { return out << e->data; } 

这个朋友只有一个模板的实例化,这个模板参数和类的模板参数相匹配。

更新:不幸的是,这是非法的。 MSVC和Comeau都拒绝了。 这提出了为什么原始的错误消息提出了几乎完全是这种方法的问题。

改变

 friend ostream& operator << (ostream& out, const Base<T>& e); 

 friend ostream& operator << <T>(ostream& out, const Base<T>& e); 

应该可以工作 – 我只是用这种方式解决了一个相同的问题。

改变

 friend ostream& operator << (ostream &out, Base<T> *e)` 

 template<T> friend ostream& operator << (ostream &out, Base *e) 

更改

 ostream& operator<< (ostream &out, Base<int> *e) { out << e->data; return out; } 

 ostream& operator<< (ostream &out, T *e) { out << e->data; return out; }