Re: Trouble with overloading << operator via friend
On May 14, 7:40 pm, Neelesh <neelesh.bo...@gmail.com> wrote:
On May 14, 4:50 pm, magnus.morab...@gmail.com wrote:
On May 14, 1:37 pm, magnus.morab...@gmail.com wrote:
I tried -
std::ostream& FS::operator<<(std::ostream& outStream, const Case&
case1)
{
return outStream << case1.name.toStdString() << " v" <<
case1.version;
}
but this gave me -
Case.cpp:49: error: =BFstd::ostream& FS::operator<<(std::ostream&, cons=
t
FS::Case&)=BF should have been declared inside =BFFS=BF
Well, the C++ standard seems to say that explicit
qualification as done above is fine:
7.3.1.2/2:
Members of a named namespace can also be defined outside that
namespace by explicit qualification
(3.4.3.2) of the name being defined, provided that the entity being
defined was already declared in the namespace and the definition
appears after the point of declaration in a namespace that encloses
the declaration=BFs namespace.
The problem is that there is no visible declaration of the
entity in question (::FS::operator<<). The friend declaration
does NOT inject the name into the surrounding namespace.
Also, 7.3.1.2/3:
If a friend declaration in a nonlocal class first declares a class or
function83) the friend class or function is a member of the innermost
enclosing namespace
This means that operator<< belongs to namespace FS and it can be
defined outside namespace FS by explicitly qualifying the name, like
FS::operator<<
The issue isn't simple, mainly (I think) for want of a good,
well established vocabulary to explain it. The friend
declaration declares a function in the immediately surrounding
namespace, but the declaration itself is in class scope, and is
treated exactly as if it were in class scope. In his code,
there is no declaration of the operator<< in scope when he tries
to define it, so his declaration is illegal.
The simplest solution, in his case, is simply to open the
namespace, and define the function (using an unqualified name)
there. More generally, he might want to provide a declaration
in namespace scope in the header, e.g.:
namespace FS {
class Case ;
std::ostream& operator<<( std::ostream&, Case const& ) ;
class Case
{
// As in his original code...
} ;
}
If he does this, then he should be able to define
std::ostream& FS::operator<<(
std::ostream& dest,
Case const& object )
{
// ...
}
without any problems.
(Another alternative would be to define the operator<< inline in
the friend declaration. This avoids the problem entirely.)
Which compiler did you try on? g++ 3.4 seems to compile this code
correctly, and I could'nt try on latest version. Comeau online,
however gives error. I'm not sure why.
In pre-standard days, a friend declaration injected the declared
name into file scope (there were no namespaces then). This
caused some problem, I forget what. (I've had it explained to
me three or four times; I just keep forgetting.) And the needed
functionality was subsumed by ADL, at least in the cases deemed
necessary. So the committee dropped the injection. Many older
compilers, however, still implement it; I think you'll find that
g++ changed with 4.0 (or something like that). (Of the
compilers I have handy, g++ 4.3.3 rejects it, but g++ 3.4.0, Sun
CC 5.8, and the VC++ from Visual Studios 8 all accept it.)
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34