Reputation:
Depending on how I write a function in my class, I get one of 2 contadictory error messages when trying to overload the <<
operator as a friend of my class. The error messages are as follows:
// With two arguments
(engine.cpp) error: 'std::ostream& game::GameEngine::operator<<( std::ostream&, const Engine& )' must take exactly one argument.
Otherwise, I get this if I try what the compiler says:
// 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'
I'm of the opinion that the one with two arguments is the correct one, but I do not understand why I am getting contradictory error messages. I'm using `-Wall, -Wextra, -pedantic-error, -std=c++11' and several other warning flags to compile the file.
engine.h source:
#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;
And, engine.cpp:
#include <iostream>
#include "engine.h"
/* ... */
std::ostream& Engine::operator<<( std::ostream& o, const Engine& engine ) {
/* ... */
}
Upvotes: 1
Views: 103
Reputation: 103741
When an operator is overloaded as a non-static member function, it takes one less argument than it would as a non-member function (or a static member function). This is because there is an implicit argument in the member version, that being the calling object. So binary operator overloads, like operator<<
, only take one argument when written as members. This argument is taken from the right hand side when the operator is called, and the left hand side is the calling object.
That's why the error messages seem to contradict each other. What you've done in the code you've shown is declared your function as a non-member function (friends are not members), but you've defined it as a member function.
In the specific case of overloading input and output stream operators for your class, you cannot overload them as non-static members of your class, because the left hand argument needs to be the stream class.
Upvotes: 0
Reputation: 18974
When you declare the function inside the class as a friend, it is a member of the enclosing namespace and not of the class itself. So you need to define it as
std::ostream& game::operator<<( std::ostream& o, const Engine& engine ) { ... }
Upvotes: 2