我有一个基类类似于下面的代码。我试图重载<<与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
我尝试添加&lt;&gt;在&lt;&lt;在类声明/原型中。但是,我得到它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;
}
我在网上其他地方读到过放&lt;&gt;之间&lt;&lt;原型中的()应该解决这个问题,但事实并非如此。我可以把它变成一个单一的功能模板吗?
答案 0 :(得分:33)
听起来你想改变:
friend ostream& operator << (ostream& out, const Base<T>& e);
要:
template<class T>
friend ostream& operator << (ostream& out, const Base<T>& e);
答案 1 :(得分:16)
Gcc正确警告你。尽管它出现了(它需要Base参数),但它不是一个函数模板。
您的类定义具有友元函数的非模板声明(没有模板),但稍后的友元函数定义是函数模板(即以模板开始..)。
您的运营商&lt;&lt;采取基础*。这是不正确的。它应该是Base const&amp;保留它的内置语义
可能你正在寻找以下内容:
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;
}
答案 2 :(得分:10)
您所寻找的可能是:
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都拒绝了它。这提出了为什么原始错误消息几乎完全建议这种方法的问题。
答案 3 :(得分:4)
改变
friend ostream& operator << (ostream& out, const Base<T>& e);
到
friend ostream& operator << <T>(ostream& out, const Base<T>& e);
也应该有效 - 我只是以这种方式解决了同样的问题。
答案 4 :(得分:0)
改变
friend ostream& operator << (ostream &out, Base<T> *e)`
要
template<T> friend ostream& operator << (ostream &out, Base *e)
答案 5 :(得分:-3)
更改
ostream& operator<< (ostream &out, Base<int> *e) {
out << e->data;
return out;
}
到
ostream& operator<< (ostream &out, T *e) {
out << e->data;
return out;
}