Re: namespace bug

AIDA Shinra <[email protected]> Sun, 13 Jul 2003 21:10:13 +0900
Newsgroups gmane.comp.gcc.cgicc.bugs
Message-ID <[email protected]>
On 2003.7.12, at 04:23 AM, Volker Wysk wrote:

> Hello
>
> In MStreamable.h, the following is defined inside the cgicc namespace:
>
> CGICC_API STDNS ostream&
> operator<<(STDNS ostream& out, const MStreamable& obj);
>
> Thus, when using "using namespace cgicc;", and not using "using 
> namespace
> std" this operator<< shadows any other operator<<'s, even for different
> argument types. That's is the normal C++ name finding procedure.
>
No. What is your compiler? It does not seem to support Koenig lookup 
properly.
For example,

namespace ns1 {
     struct Type1 {};
     void foo(Type1, Type1) {}
}
namespace ns2 {
     struct Type2 : ns1::Type1 {}:
     void foo(Type1, Type2) {}
}
using namespace ns1;
int main(int, const char *const *) {
     foo(Type1(), ns2::Type2());
     return 0;
}

First both ns1::foo() and ns2::foo() are choosed as foo()'s canditates. 
Then normal
overload solution is performed. Then ns2::foo() is invoked. Therefore,

> The operator<< should be defined outside any namespaces.
No. Operators should be defined inside corresponding namespaces to 
their arguments.
If you define them in the global namespace, real hiding problems occur.

namespace ns1 {
     struct Type1 {};
}
void foo(Type1) {}
namespace ns2 {
     struct Type2 {};
     void foo(Type2) {}

     template <class T>
     void bar(T t) {
         foo(t);
     }
}

int main(int, const char *const *) {
     ns2::bar(ns1::Type1());  // does not compile
     return 0;
}

 From ns2::bar<ns1::Type1>() only ns2::foo() is visible. To avoid this 
problem you need to
define foo(Type1) inside ns1. Then Koenig lookup finds both of foo()s.