运算符<<必须采取一个参数

时间:2012-05-24 20:26:47

标签: c++ operator-overloading iostream

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&lt;&lt;(std :: ostream&amp;,A&amp;)'必须只接受一个参数。

有什么问题?

4 个答案:

答案 0 :(得分:109)

问题是你在类中定义它,

a)表示第二个参数是隐式的(this)和

b)它不会做你想做的事,即扩展std::ostream

您必须将其定义为自由函数:

class A { /* ... */ };
std::ostream& operator<<(std::ostream&, const A& a);

答案 1 :(得分:46)

朋友功能不是会员功能,所以问题是您将operator<<声明为A的朋友:

 friend ostream& operator<<(ostream&, A&);

然后尝试将其定义为类logic

的成员函数
 ostream& logic::operator<<(ostream& os, A& a)
          ^^^^^^^

您是否对logic是类还是命名空间感到困惑?

错误是因为你试图定义一个带有两个参数的成员operator<<,这意味着它需要三个参数,包括隐式this参数。运算符只能接受两个参数,因此当您编写a << b时,两个参数为ab

您希望将ostream& operator<<(ostream&, const A&)定义为 -member函数,绝对不是logic的成员,因为它与该类无关!

std::ostream& operator<<(std::ostream& os, const A& a)
{
  return os << a.number;
}

答案 2 :(得分:0)

如果将operator<<定义为成员函数,它将与使用非成员operator<<时具有不同的分解语法。非成员operator<<是二元运算符,成员operator<<是一元运算符。

// Declarations
struct MyObj;
std::ostream& operator<<(std::ostream& os, const MyObj& myObj);

struct MyObj
{
    // This is a member unary-operator, hence one argument
    MyObj& operator<<(std::ostream& os) { os << *this; return *this; }

    int value = 8;
};

// This is a non-member binary-operator, 2 arguments
std::ostream& operator<<(std::ostream& os, const MyObj& myObj)
{
    return os << myObj.value;
}

所以...。您如何称呼他们?运算符在某些方面很奇怪,我将挑战您在脑海中写出operator<<(...)语法以使事情变得有意义。

MyObj mo;

// Calling the unary operator
mo << std::cout;

// which decomposes to...
mo.operator<<(std::cout);

或者您可以尝试调用非成员二进制运算符:

MyObj mo;

// Calling the binary operator
std::cout << mo;

// which decomposes to...
operator<<(std::cout, mo);

您没有义务使这些运算符成为成员函数时表现直观,可以定义operator<<(int)以使某些成员变量左移(如果需要),以了解人们可能会措手不及,无论您可以写多少条评论。

几乎最后,有时操作员调用的两个分解都有效,您在这里可能会遇到麻烦,我们将推迟进行对话。

最后,请注意编写一个看起来像二进制运算符的一元成员运算符可能会很奇怪(因为您可以使成员运算符成为虚拟的.....也尝试不放行并沿此路径运行。 ...)

struct MyObj
{
    // Note that we now return the ostream
    std::ostream& operator<<(std::ostream& os) { os << *this; return os; }

    int value = 8;
};

这种语法现在会激怒许多编码人员。...

MyObj mo;

mo << std::cout << "Words words words";

// this decomposes to...
mo.operator<<(std::cout) << "Words words words";

// ... or even further ...
operator<<(mo.operator<<(std::cout), "Words words words");

请注意cout是这里链中的第二个参数。...奇怪吗?

答案 3 :(得分:0)

运算符重载包括成员函数重载和非成员函数重载,两者不能混用。 https://condor.depaul.edu/ntomuro/courses/262/notes/lecture3.html