If I make Format() public, the compiler is happy.
If Format() is private, the compiler complains that it's inaccessible.
I really don't want to make Format() public.
Since operator << is a friend function, shouldn't Format() be accessible even if it's private?
The name of the friend is not found by simple name lookup until a matching declaration is provided in that namespace scope (either before or after the class declaration granting friendship).
In other words, it's not matching your friend declaration to the definition simply by "using namespace XYZ;" because the standard apparently explicitly prevents that. (Why? I dunno.)
(I think, I'm not a language lawyer.)
If you take the friend function outside the namespace the program fails for several reasons. Try it.
If a program is written such that a namespace is specified the using namespace line is obvious. Neither of those two are bad habits. They naturally follow from the appropriate/valid use of namespace.
The usual aversion to namespace-ing on this site applies to usingnamespace std; which some just can't get over in ramming into beginners.
OP wanted a certain functionality and got it. There's no big deal AFAICS.
Ganado actually hit upon the idea of how to solve it but simply didn't extend the namespace to the whole class. There is no reason not to do just that. In fact it solves the problem raised by the OP as the program demonstrates.
againtrys code works as posted, however, it's going to be problematic.
He included the implementation of operator << and OBJTYPE::Format() (lines 15-24) inside the namespace declaration. Assuming the declaration of OBJTYPE and it's enclosing namespace declaration are in a .h file, that's going to cause multiply defined symbols to the linker assuming the .h file is included in multiple places.
However, putting the implementation of the operator inside a namespace declaration in the .cpp file does work and avoids multiply defined symbols.
I confess, I don't actually understand why this works and, in the light of another thread where I got a hammering, I admit that I don't know whether it is good practice or not. (Ignore the usingnamespace std; bit.)
All I have done is treated the class as anyone normally would, including a private Format method, then placing it in a namespace. It’s as simple as that.
If you want to use anything in that namespace, then use using ..., or use :: , please yourself.
I was well aware before I posted that the header and implementation files aren’t separate, but faulting that consideration is nonsense. There is absolutely nothing to gain in following that line without concrete proof.
In any case, even if it was right, which it isn’t I doubt whether too many real programmers have time enough to get down in the weeds and sweat too much about the niceties of an armchair linker. If they did they would find cppreference is seriously flawed, which it isn’t :)
lastchance,
I believe it works because adding that declaration on line 9 fulfills the following emphasized text:
the standard wrote:
The name of the friend is not found by simple name lookup until a matching declaration is provided in that namespace scope (either before or after the class declaration granting friendship).