Help | Site Map
Connecting Tech Pros Worldwide
 
 
LinkBack Thread Tools
  #1  
Old July 25th, 2005, 08:15 PM
Marcin Kalicinski
Guest
 
Posts: n/a
Default 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
}





  #2  
Old July 25th, 2005, 08:25 PM
mrstephengross
Guest
 
Posts: n/a
Default 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

  #3  
Old July 25th, 2005, 08:35 PM
Dan Cernat
Guest
 
Posts: n/a
Default 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

  #4  
Old July 25th, 2005, 08:35 PM
Marcin Kalicinski
Guest
 
Posts: n/a
Default 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
}


  #5  
Old July 25th, 2005, 08:45 PM
mrstephengross
Guest
 
Posts: n/a
Default 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

  #6  
Old July 25th, 2005, 09:05 PM
Marcin Kalicinski
Guest
 
Posts: n/a
Default 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?


  #7  
Old July 26th, 2005, 01:15 PM
Dan Cernat
Guest
 
Posts: n/a
Default 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

  #8  
Old July 27th, 2005, 06:15 PM
Ben Pope
Guest
 
Posts: n/a
Default 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...
  #9  
Old August 3rd, 2005, 06:15 AM
Wisdo Tang
Guest
 
Posts: n/a
Default 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


 

Bookmarks

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are Off
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

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.
Post your question now . . .
It's fast and it's free

Popular Articles