Im trying to do an override on a simple struct like this:
struct Node {
int data1;
int data2;
ostream& operator<<(ostream &o,
operator<<
needs two operands. There are two ways to define an operator<<
overload function between two types.
As a member function. That's how operator<<
overloads between std::basic_ostream
and some of the basic types are defined. When you use std:cout << 10;
, it gets resolved to the overload operator std::basic_ostream<char>::operator<<(int)
When you define it as member function, the LHS of the operator is an instance of the class. The RHS of the operator is the argument to the function. That's why when you define it as member function, it can only have one argument.
As a free function. That's how operator<<
overloads between std::basic_ostream
and custom types are defined. These functions must have two arguments. The first argument is the LHS of the operator and the second argument is the RHS of the operator.
For this reasons, you have to define operator<<
overload between std::ostream
and your class as a free function, with std::ostream&
as the first argument type and Node const&
as the second argument type.
std::ostream& operator<<(std:ostream& os, Node const& node);
At times like these, I wish the standard library had implemented a function:
template <typename T>
std::ostream& operator<<(std::ostream& os, T const& t)
{
return t.serialize(os);
}
Then, any class could provide the function
std::ostream& serialize(std::ostream& os) const;
and be ready to be used like all the basic types with std::ostream
.
std::ostream& operator<<(std::ostream&, ...)
needs to be a free function.
Move it outside the class and it will work.
The reason it is so is because defining operator<<(std::ostream&)
(or other binary operators) inside the class implies that object is the LHS operand. You would have to write smth crazy like:
Node << std::cout;