矛盾的错误消息 - 运算符重载<<

时间:2015-03-09 22:00:30

标签: c++ operator-overloading syntax-error friend

问题

根据我在课堂上编写函数的方式,当我尝试将<<运算符作为我班级的朋友重载时,我会收到2条contadictory错误消息之一。错误消息如下:

// With two arguments
(engine.cpp) error: 'std::ostream& game::GameEngine::operator<<( std::ostream&, const Engine& )' must take exactly one argument.

否则,如果我尝试编译器所说的话,我会得到这个:

// With 1 argument
(engine.h) error: 'std::ostream& game::operator<<( std::ostream& )' must take exactly two arguments.
(engine.cpp) error: no 'std::ostream& game::GameEngine::operator<<( std::ostream& )' member function declared in class 'game::GameEngine'

我认为有两个参数的那个是正确的,但我不明白为什么我会得到相互矛盾的错误信息。我使用`-Wall,-Wextra,-pedantic-error,-std = c ++ 11&#39;和其他几个警告标志来编译文件。

代码

engine.h来源:

#include <iostream>
namespace game {
    // Note that all variables and functions except the operator overload are static.
    class GameEngine {
    public:
      /* ... */
      friend std::ostream& operator<<( std::ostream& o, const GameEngine& engine );
    private:
      /* ... */
    }
    typedef game::GameEngine Engine;

并且,engine.cpp:

#include <iostream>
#include "engine.h"
/* ... */
std::ostream& Engine::operator<<( std::ostream& o, const Engine& engine ) {
    /* ... */
}

2 个答案:

答案 0 :(得分:2)

当您将类中的函数声明为朋友时,它是封闭命名空间的成员,而不是类本身的成员。所以你需要将其定义为

std::ostream& game::operator<<( std::ostream& o, const Engine& engine ) { ... }

答案 1 :(得分:0)

当运算符作为非静态成员函数重载时,它比非成员函数(或静态成员函数)少一个参数。这是因为成员版本中存在隐式参数,即调用对象。因此二进制运算符重载(如operator<<)在写为成员时只接受一个参数。调用运算符时,此参数取自右侧,左侧是调用对象。

这就是为什么错误消息似乎互相矛盾的原因。您在已经显示的代码中所做的是宣布您的功能是非会员功能(朋友不是会员),但您已将其定义为会员功能。

在为您的类重载输入和输出流操作符的特定情况下,您不能将它们作为类的非静态成员重载,因为左侧参数需要是流类。