By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,924 Members | 1,142 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,924 IT Pros & Developers. It's quick & easy.

Cross-namespace name lookup

P: n/a
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
}

Jul 25 '05 #1
Share this Question
Share on Google+
8 Replies


P: n/a
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

Jul 25 '05 #2

P: n/a


Marcin Kalicinski wrote:
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
}


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

Jul 25 '05 #3

P: n/a
> 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?


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
}
Jul 25 '05 #4

P: n/a
>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 :-(


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

Jul 25 '05 #5

P: n/a
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?
Jul 25 '05 #6

P: n/a
See my comment before main()
Marcin Kalicinski wrote:
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;}
}

// let the compiler know where else to look up the names
using namespace N3;

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?


it should compile now.

/dan

Jul 26 '05 #7

P: n/a
Marcin Kalicinski wrote:
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?


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...
Jul 27 '05 #8

P: n/a

"Dan Cernat" <dc*****@excite.com> дʼ
news:11**********************@g44g2000cwa.googlegr oups.com...
See my comment before main()
Marcin Kalicinski wrote:
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;}
}

// let the compiler know where else to look up the names
using namespace N3;

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?


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?


it should compile now.

/dan


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
Aug 3 '05 #9

This discussion thread is closed

Replies have been disabled for this discussion.