a.h
#include "logic.h"
...
class A
{
friend ostream& operator<<(ostream&, A&);
...
};
logic.cpp
#include "a.h"
...
ostream& logic::operator<<(ostream& os, A& a)
{
...
}
...
当我编译时,它说:
std::ostream& logic::operator<<(std::ostream&,A&)‘必须只有一个参数。
有什么问题吗?
发布于 2012-05-25 04:28:54
问题是您在类中定义它,这
a)表示第二个参数是隐式的(this
),并且
b)它不会做你想做的事情,也就是扩展std::ostream
。
你必须将它定义为一个自由函数:
class A { /* ... */ };
std::ostream& operator<<(std::ostream&, const A& a);
发布于 2012-05-25 05:13:53
友元函数不是成员函数,所以问题是您将operator<<
声明为A
的友元
friend ostream& operator<<(ostream&, A&);
然后尝试将其定义为类logic
的成员函数
ostream& logic::operator<<(ostream& os, A& a)
^^^^^^^
您是否对logic
是类还是名称空间感到困惑?
错误是因为您试图定义一个带有两个参数的成员operator<<
,这意味着它需要包括隐式this
参数在内的三个参数。运算符只能接受两个参数,因此当您编写a << b
时,两个参数是a
和b
。
您希望将ostream& operator<<(ostream&, const A&)
定义为非-member函数,而不是logic
的成员,因为它与该类无关!
std::ostream& operator<<(std::ostream& os, const A& a)
{
return os << a.number;
}
发布于 2017-06-23 10:27:18
我在使用模板化类时遇到了这个问题。下面是我不得不使用的一个更通用的解决方案:
template class <T>
class myClass
{
int myField;
// Helper function accessing my fields
void toString(std::ostream&) const;
// Friend means operator<< can use private variables
// It needs to be declared as a template, but T is taken
template <class U>
friend std::ostream& operator<<(std::ostream&, const myClass<U> &);
}
// Operator is a non-member and global, so it's not myClass<U>::operator<<()
// Because of how C++ implements templates the function must be
// fully declared in the header for the linker to resolve it :(
template <class U>
std::ostream& operator<<(std::ostream& os, const myClass<U> & obj)
{
obj.toString(os);
return os;
}
现在:*如果我的toString()函数要隐藏在cpp中,它就不能是内联的。*你被头中的一些代码卡住了,我无法摆脱它。*操作符将调用toString()方法,它不是内联的。
operator<<的主体可以在friend子句中声明,也可以在类外部声明。这两种选择都很丑陋。:(
也许我误解或遗漏了什么,但只是向前声明运算符模板并不会链接到gcc。
这也行得通:
template class <T>
class myClass
{
int myField;
// Helper function accessing my fields
void toString(std::ostream&) const;
// For some reason this requires using T, and not U as above
friend std::ostream& operator<<(std::ostream&, const myClass<T> &)
{
obj.toString(os);
return os;
}
}
我认为,如果使用未模板化的父类实现operator<<,并使用虚拟toString()方法,还可以避免强制在头部中声明的模板化问题。
https://stackoverflow.com/questions/10744787
复制相似问题