自相矛盾的错误消息 - 运算符重载 <<
Contradictory Error Messages - Operator Overloading <<
问题
根据我在 class 中编写函数的方式,当我尝试重载 <<
运算符作为 class 的朋友时,我收到了 2 条相互矛盾的错误消息之一。报错信息如下:
// 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”和其他几个警告标志来编译文件。
代码
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 ) {
/* ... */
}
当运算符作为非静态成员函数重载时,它比作为非成员函数(或静态成员函数)少一个参数。这是因为在成员版本中有一个隐式参数,即调用对象。因此二元运算符重载,如 operator<<
,在写成成员时只接受一个参数。这个参数是调用operator时右边取的,左边是调用对象
这就是错误消息似乎相互矛盾的原因。您在显示的代码中所做的是将您的函数声明为非成员函数(朋友不是成员),但您已将其定义为成员函数。
在为您的 class 重载输入和输出流运算符的特定情况下,您不能将它们重载为 class 的非静态成员,因为左侧参数需要是流 class.
当您将 class 中的函数声明为友元时,它是封闭命名空间的成员,而不是 class 本身的成员。所以你需要定义为
std::ostream& game::operator<<( std::ostream& o, const Engine& engine ) { ... }
问题
根据我在 class 中编写函数的方式,当我尝试重载 <<
运算符作为 class 的朋友时,我收到了 2 条相互矛盾的错误消息之一。报错信息如下:
// 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”和其他几个警告标志来编译文件。
代码
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 ) {
/* ... */
}
当运算符作为非静态成员函数重载时,它比作为非成员函数(或静态成员函数)少一个参数。这是因为在成员版本中有一个隐式参数,即调用对象。因此二元运算符重载,如 operator<<
,在写成成员时只接受一个参数。这个参数是调用operator时右边取的,左边是调用对象
这就是错误消息似乎相互矛盾的原因。您在显示的代码中所做的是将您的函数声明为非成员函数(朋友不是成员),但您已将其定义为成员函数。
在为您的 class 重载输入和输出流运算符的特定情况下,您不能将它们重载为 class 的非静态成员,因为左侧参数需要是流 class.
当您将 class 中的函数声明为友元时,它是封闭命名空间的成员,而不是 class 本身的成员。所以你需要定义为
std::ostream& game::operator<<( std::ostream& o, const Engine& engine ) { ... }