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:
stream& FS:
perator<<(std:
stream& outStream, const Case&
> > case1)
> > {
> > return outStream << case1.name.toStdString() << " v" <<
> > case1.version;
> > }
> > but this gave me -
> > Case.cpp:49: error: ¿std:
stream& FS:
perator<<(std:
stream&, const
> > FS::Case&)¿ should have been declared inside ¿FS¿
> 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¿s namespace.
The problem is that there is no visible declaration of the
entity in question (::FS:

perator<<). 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:
perator<<
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:

stream& operator<<( std:

stream&, Case const& ) ;
class Case
{
// As in his original code...
} ;
}
If he does this, then he should be able to define
std:

stream& FS:

perator<<(
std:

stream& 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:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34