Consider bar.h:
#include <iostream>
namespace foo {
class Bar {
public:
friend std::ostream& operator <<(std::ostream& output, const Bar&);
private:
int xx_;
};
}
Consider bar.cc:
#include "bar.h"
std::ostream& operator<<(std::ostream& output, const foo::Bar &in) {
output << in.xx_ << std::endl;
return output;
}
Why can't the implementation for operator << access the private member from the Bar class? That is:
$ icpc -c bar.cc
bar.cc(5): error #308: member "foo::Bar::xx_" (declared at line 9 of "bar.h") is inaccessible
output << in.xx_ << std::endl;
^
compilation aborted for bar.cc (code 2)
I solved the problem by embedding the implementation for operator << inside the foo namespace, i.e.:
namespace foo {
std::ostream& operator<<(std::ostream& output, const foo::Bar &in) {
output << in.xx_ << std::endl;
return output;
}
}
Yet... is this the correct way of solving this problem? Isn't this approach giving away details of the implementation?
Question:
is this the correct way of solving this problem?
Answer:
Yes, it is the correct way of solving the problem.
Question:
Isn't this approach giving away details of the implementation?
Answer:
Not at all.
The line
friend std::ostream& operator <<(std::ostream& output, const Bar&);
declares the function as an external function in the namespace in which the class is defined. If the class is not defined in a namespace, the function is declared as an external function in the global namespace. Since the function is declared as a external function in the foo
namespace, it MUST be defined in that namespace.
If you want that function to be a global function, outside the foo
namesapce, you have to use:
namespace foo
{
class Bar;
}
std::ostream& operator <<(std::ostream& output, const foo::Bar&);
namespace foo {
class Bar {
public:
friend std::ostream& operator <<(std::ostream& output, const Bar&);
private:
int xx_;
};
}