
July 25th, 2005, 08:15 PM
| | | Cross-namespace name lookup
Is the code below ill formed (because operator >> is defined in different
namespace than class B)?
It fails with VS 2005 Beta. I don't know if I should redesign my code or if
I should find a better compiler?
namespace N1
{
class A { };
std::istream &operator >>(std::istream &, A &);
}
namespace N2
{
class B: public A { };
}
void f()
{
A a;
B b;
cin >> a; // OK
cin >> b; // Error: cannot find a matching operator >> for class B
} | 
July 25th, 2005, 08:25 PM
| | | Re: Cross-namespace name lookup
Interesting... I guess the search rules don't include namespaces of
base classes... Could you cast the B instance as an A ("cin >> (A)b") ?
Or could you put the operator>>() definition in the std namespace?
--Steve | 
July 25th, 2005, 08:35 PM
| | | Re: Cross-namespace name lookup
Marcin Kalicinski wrote:[color=blue]
> Is the code below ill formed (because operator >> is defined in different
> namespace than class B)?
>
> It fails with VS 2005 Beta. I don't know if I should redesign my code or if
> I should find a better compiler?
>
> namespace N1
> {
> class A { };
> std::istream &operator >>(std::istream &, A &);
> }
>
> namespace N2
> {
> class B: public A { };
> }
>
> void f()
> {
> A a;
> B b;
> cin >> a; // OK
> cin >> b; // Error: cannot find a matching operator >> for class B
> }[/color]
This is not the real code, is it? I copy-pasted this code in VS 2003
and I cannot compile the declaration of B since its base class is in a
different namespace. That is why I doubt this is real code.
The code below compiles:
#include <iostream>
namespace N1
{
class A { };
std::istream &operator >>(std::istream & x, A &){return x;}
}
namespace N2
{
class B: public N1::A { };
}
int main()
{
N1::A a;
N2::B b;
std::cin >> a; // OK
std::cin >> b; // OK
return 0;
}
/dan | 
July 25th, 2005, 08:35 PM
| | | Re: Cross-namespace name lookup
> Interesting... I guess the search rules don't include namespaces of[color=blue]
> base classes... Could you cast the B instance as an A ("cin >> (A)b") ?
> Or could you put the operator>>() definition in the std namespace?[/color]
Possibly both of these solve the problem. Unforunately, I probably cannot
use any of them! First, function f in my code is actually a template:
template<class T> void f(T &t) { cin >> t; }
So I cannot make the cast :-(
Second, putting anything in std namespace is undefined behavior, as far as I
remember C++ standard.
The original code again:
namespace N1
{
class A { };
std::istream &operator >>(std::istream &, A &);
}
namespace N2
{
class B: public A { };
}
void f()
{
A a;
B b;
cin >> a; // OK
cin >> b; // Error: cannot find a matching operator >> for class B
} | 
July 25th, 2005, 08:45 PM
| | | Re: Cross-namespace name lookup
>Possibly both of these solve the problem. Unforunately, I probably cannot
use any of them! First, function f in my code is actually a template:
[color=blue]
>template<class T> void f(T &t) { cin >> t; }[/color]
[color=blue]
>So I cannot make the cast :-([/color]
Yes you can! :) Here's how:
#include "boost/mpl/is_same.hpp"
struct streamAsNormal { template<typename T> static void go(const
std::istream & i, T & t) { i >> t; } };
struct streamAsBase { template<typename T> static void go(const
std::istream & i, T & t) { i >> (A)t; } };
template<class T> void f(T &t)
{
boost::if<boost::is_same<T, B>::type, streamAsBase,
streamAsNormal>::type::go(cin, t);
}
--Steve | 
July 25th, 2005, 09:05 PM
| | | Re: Cross-namespace name lookup
Hi,
Yes, you're right. The code is not real, I wrote it only to illustrate the
real problem found in my program. Of course I forgot the namespace qualifier
in class B definition.
I'm sorry to say that but it really compiles, as you said. So I started
digging deeper in my code and found out that the real problem is different
(see bottom for new code). I'm saying sorry to all the people who answered
my initial post...
// The code illustrating the problem:
namespace N1
{
class A { };
}
namespace N2
{
class B: public N1::A { };
}
namespace N3
{
std::istream &operator >>(std::istream & x, N1::A &){return x;}
}
int main()
{
N1::A a;
N2::B b;
std::cin >> a; // Error
std::cin >> b; // Error
return 0;
}
I would like to move operator >> to namespace N1 very much, but I cannot
because namespace N1 is actually namespace std, and class N1::A is
std::vector. Maybe the whole idea of defining stream operations for std
containers is bad? | 
July 26th, 2005, 01:15 PM
| | | Re: Cross-namespace name lookup
See my comment before main()
Marcin Kalicinski wrote:[color=blue]
> Hi,
>
> Yes, you're right. The code is not real, I wrote it only to illustrate the
> real problem found in my program. Of course I forgot the namespace qualifier
> in class B definition.
>
> I'm sorry to say that but it really compiles, as you said. So I started
> digging deeper in my code and found out that the real problem is different
> (see bottom for new code). I'm saying sorry to all the people who answered
> my initial post...
>
> // The code illustrating the problem:
>
> namespace N1
> {
> class A { };
> }
>
> namespace N2
> {
> class B: public N1::A { };
> }
>
> namespace N3
> {
> std::istream &operator >>(std::istream & x, N1::A &){return x;}
> }
>[/color]
// let the compiler know where else to look up the names
using namespace N3;
[color=blue]
> int main()
> {
> N1::A a;
> N2::B b;
> std::cin >> a; // Error
> std::cin >> b; // Error
> return 0;
> }
>
> I would like to move operator >> to namespace N1 very much, but I cannot
> because namespace N1 is actually namespace std, and class N1::A is
> std::vector. Maybe the whole idea of defining stream operations for std
> containers is bad?[/color]
it should compile now.
/dan | 
July 27th, 2005, 06:15 PM
| | | Re: Cross-namespace name lookup
Marcin Kalicinski wrote:[color=blue]
> Hi,
>
> Yes, you're right. The code is not real, I wrote it only to illustrate the
> real problem found in my program. Of course I forgot the namespace qualifier
> in class B definition.
>
> I'm sorry to say that but it really compiles, as you said. So I started
> digging deeper in my code and found out that the real problem is different
> (see bottom for new code). I'm saying sorry to all the people who answered
> my initial post...
>
> // The code illustrating the problem:
>
> namespace N1
> {
> class A { };
> }
>
> namespace N2
> {
> class B: public N1::A { };
> }
>
> namespace N3
> {
> std::istream &operator >>(std::istream & x, N1::A &){return x;}
> }
>
> int main()
> {
> N1::A a;
> N2::B b;
> std::cin >> a; // Error
> std::cin >> b; // Error
> return 0;
> }
>
> I would like to move operator >> to namespace N1 very much, but I cannot
> because namespace N1 is actually namespace std, and class N1::A is
> std::vector. Maybe the whole idea of defining stream operations for std
> containers is bad?[/color]
std::vector doesn't have a virtual destructor, are you sure you want to inherit from it?
Perhaps you should compose B from a std::vector, might solve your problems, too.
Ben
--
I'm not just a number. To many, I'm known as a String... | 
August 3rd, 2005, 06:15 AM
| | | Re: Cross-namespace name lookup
"Dan Cernat" <dcernat@excite.com> дÈëÓʼþ
news:1122379825.431656.130450@g44g2000cwa.googlegr oups.com...[color=blue]
> See my comment before main()
>
>
> Marcin Kalicinski wrote:[color=green]
> > Hi,
> >
> > Yes, you're right. The code is not real, I wrote it only to illustrate[/color][/color]
the[color=blue][color=green]
> > real problem found in my program. Of course I forgot the namespace[/color][/color]
qualifier[color=blue][color=green]
> > in class B definition.
> >
> > I'm sorry to say that but it really compiles, as you said. So I started
> > digging deeper in my code and found out that the real problem is[/color][/color]
different[color=blue][color=green]
> > (see bottom for new code). I'm saying sorry to all the people who[/color][/color]
answered[color=blue][color=green]
> > my initial post...
> >
> > // The code illustrating the problem:
> >
> > namespace N1
> > {
> > class A { };
> > }
> >
> > namespace N2
> > {
> > class B: public N1::A { };
> > }
> >
> > namespace N3
> > {
> > std::istream &operator >>(std::istream & x, N1::A &){return x;}
> > }
> >[/color]
>
> // let the compiler know where else to look up the names
> using namespace N3;
>
>[color=green]
> > int main()
> > {
> > N1::A a;
> > N2::B b;
> > std::cin >> a; // Error
> > std::cin >> b; // Error
> > return 0;
> > }
> >
> > I would like to move operator >> to namespace N1 very much, but I cannot
> > because namespace N1 is actually namespace std, and class N1::A is
> > std::vector. Maybe the whole idea of defining stream operations for std
> > containers is bad?[/color][/color]
The idea is no bad, but the namespace look up mechanism can't auto find
operators.
Giving thee using namespace is OK when using it.
You indeed expect the operators can be found automatically?
[color=blue]
>
> it should compile now.
>
> /dan
>[/color]
No, it doesn't pass still.
I think the compile can't find the operator>> in the statement
std::cin,isn't it.
Wisdo Tang |
Posting Rules
| You may not post new threads You may not post replies You may not post attachments You may not edit your posts HTML code is Off | | | | | | What is Bytes?
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over network members.
|