I would like to define an ostream operator to let me easily output variables of type alglib::complex
. To provide a working example without including the alglib library I'll instead overload the output of complex<double>
below (this clarification because of an earlier version of the question). In the header file "my_class.h" I have
using namespace std;
#include <complex>
#include <iostream>
class my_class {
public:
ostream& operator << (std::ostream& os, complex<double> a) {
os << "(" << real(a) << "," << imag(a) << ")";
return os;
}
void output(complex<double>);
my_class() {}
~my_class() {}
};
And in the source file "my_class.cpp" I have
#include "my_class.h"
void my_class::output(complex<double> cd) {
cout << cd << endl;
}
Finally I have a main method file "run_my_class.cpp":
#include "my_class.h"
int main(int argc, const char* argv[]) {
my_class obj;
complex<double> cd=complex<double>(1.0,-1.0);
obj.output(cd);
}
I try to compile using
g++ -c my_class.cpp
but this gives me the error
my_class.h:9:62: error: ‘std::ostream& my_class::operator<<(std::ostream&, std::complex<double>)’ must take exactly one argument
ostream& operator << (std::ostream& os, complex<double> a) {
However, if I define the operator as a friend, namely friend ostream& operator << (std::ostream& os, complex<double> a)
, it compiles and I compile the main method:
g++ run_my_class.cpp my_class.o -o run_my_class
And it works as it should. However this is not what it seems the friend
keyword is for. Is there a better way to make this work?
Since operator <<
will be called on an std::ostream
, you cannot define this procedure as a member function for my_class
, you have to define it as a global function, since it's an operation for std::ostream
, not my_class
.
By putting the friend
keyword into the declaration, you are saying that you want to declare the operator <<
as a friend global function (not a member function!). The C++ standard lets you put the definition of the friend function there, but it won't be a member function. It is the same as the following, which is more clear:
#include <complex>
#include <iostream>
class my_class {
public:
friend ostream& operator << (std::ostream& os, complex<double> a);
void output(complex<double>);
my_class() {}
~my_class() {}
};
std::ostream& operator << (std::ostream& os, complex<double> a) {
os << "(" << real(a) << "," << imag(a) << ")";
return os;
}
As it was already pointed out in the comments, the usage of friend
is not necessary here.
Irrelevant to the question, but please be aware that resolving namespaces in a header file is generally a really-really bad idea, since all other files including it will implicitly resolve that namespace too. It can easily lead to vexing compilation errors in the long run.