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

operator >> needs to be in namespace std??

P: n/a
template < typename T >
std::istream & operator >(std::istream & in, std::pair<T,T& p)
{
in >p.first >p.second;
return in;
}
....
std::istream_iterator< std::pair<size_type, size_type
in_beg(std::cin), in_end;
....
fails to compile. Wrapping the operator >for the pair in namespace
std {} works. Since you're not "allowed" to insert stuff into
namespace std why is that seemingly required and how could this be done
without that?

Dec 18 '06 #1
Share this Question
Share on Google+
11 Replies


P: n/a
Noah Roberts wrote:
template < typename T >
std::istream & operator >(std::istream & in, std::pair<T,T& p)
{
in >p.first >p.second;
return in;
}
...
std::istream_iterator< std::pair<size_type, size_type
in_beg(std::cin), in_end;
...
fails to compile. Wrapping the operator >for the pair in namespace
std {} works. Since you're not "allowed" to insert stuff into
namespace std why is that seemingly required and how could this be done
without that?
Looks like an ADL thing. Care to post a complete example so I can try to
compile it here? I want to be sure I'm doing things exactly as you are.
I'm not sure what the ramifications of std::operator>>(...) might be.

--
NOUN:1. Money or property bequeathed to another by will. 2. Something handed
down from an ancestor or a predecessor or from the past: a legacy of
religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/
Dec 18 '06 #2

P: n/a
Noah Roberts wrote:
template < typename T >
std::istream & operator >(std::istream & in, std::pair<T,T& p)
{
in >p.first >p.second;
return in;
}
...
std::istream_iterator< std::pair<size_type, size_type
in_beg(std::cin), in_end;
...
fails to compile. Wrapping the operator >for the pair in namespace
std {} works. Since you're not "allowed" to insert stuff into
namespace std why is that seemingly required and how could this be done
without that?
I thought you were allowed to add things to the std namespace (namely
overloads of pre-existing operators - just like this). There was a
discussion about this a couple of years ago, and I do remember two sides
of the argument, however I can't remember how definitive the discussion was.
Dec 18 '06 #3

P: n/a
Gianni Mariani wrote:
Noah Roberts wrote:
>template < typename T >
std::istream & operator >(std::istream & in, std::pair<T,T& p)
{
in >p.first >p.second;
return in;
}
...
std::istream_iterator< std::pair<size_type, size_type
in_beg(std::cin), in_end;
...
fails to compile. Wrapping the operator >for the pair in namespace
std {} works. Since you're not "allowed" to insert stuff into
namespace std why is that seemingly required and how could this be done
without that?

I thought you were allowed to add things to the std namespace (namely
overloads of pre-existing operators - just like this).
Curiously, this works:

#include <iostream>

template < typename T >
std::ostream& operator<<(std::ostream& out, std::pair<T,T>& p) {
return out << p.first << p.second;
}
int main() {
std::pair<int,intp(1,4);
std::cout<<p<<std::endl;
}

In truth, even if adding the symbol to std works and is "acceptable", I
would like to know why it is necessary.
There was a
discussion about this a couple of years ago, and I do remember two sides
of the argument, however I can't remember how definitive the discussion
was.
I defer to the Standard.
--
NOUN:1. Money or property bequeathed to another by will. 2. Something handed
down from an ancestor or a predecessor or from the past: a legacy of
religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/
Dec 18 '06 #4

P: n/a

Gianni Mariani wrote:
I thought you were allowed to add things to the std namespace (namely
overloads of pre-existing operators - just like this). There was a
discussion about this a couple of years ago, and I do remember two sides
of the argument, however I can't remember how definitive the discussion was.
Took a sec to find it but it's there:

17.4.3.1 is where it states a program can't add declarations or
definitions to namespace std. However, it states you *can* add
template specializations. "Such a specialization (complete or partial)
of a standard library template results in undefined behavior unless the
declaration depends on a user-defined name of external linkage and
unless the specialization meets the standard library requirements for
the original template."

I'm a little confused here though. Why is it *necissary* that operator
>be defined in namespace std? Does that function qualify as a template specialization?
Dec 18 '06 #5

P: n/a
Noah Roberts wrote:
Gianni Mariani wrote:
>I thought you were allowed to add things to the std namespace (namely
overloads of pre-existing operators - just like this). There was a
discussion about this a couple of years ago, and I do remember two sides
of the argument, however I can't remember how definitive the discussion
was.

Took a sec to find it but it's there:

17.4.3.1 is where it states a program can't add declarations or
definitions to namespace std. However, it states you *can* add
template specializations. "Such a specialization (complete or partial)
of a standard library template results in undefined behavior unless the
declaration depends on a user-defined name of external linkage and
unless the specialization meets the standard library requirements for
the original template."

I'm a little confused here though. Why is it *necissary* that operator
>>be defined in namespace std? Does that function qualify as a template
specialization?
It does not count as a template specialization. It is a definition of a
brand new template. And I am afraid, reading the text of the standard you
posted, that it is not "legal".

However there is another "rule" you break: do not use std::pair for your own
types. Use them as members, or private inheritance, but not directly as a
user defined type.

For the practical side: if you are only using this printing function as a
debugging tool, I would say you are quite safe and it will work as expected.

....I am just thinking that does a template instance of std::pair count as
user defined type... But I don't think it does. It would not make sense.
But I am not a language lawyer so I might be very wrong.
--
WW aka Attila
:::
Business - the art of extracting money from another man's pocket without
resorting to violence. -- Max Amsterdam
Dec 19 '06 #6

P: n/a
White Wolf schrieb:
However there is another "rule" you break: do not use std::pair for your own
types. Use them as members, or private inheritance, but not directly as a
user defined type.
Why not ?
...
Stefan
--
Stefan Naewe
stefan_DOT_naewe_AT_atlas_DOT_de
Dec 19 '06 #7

P: n/a

Stefan Naewe wrote:
White Wolf schrieb:
However there is another "rule" you break: do not use std::pair for your own
types. Use them as members, or private inheritance, but not directly as a
user defined type.

Why not ?
bump...

yeah, why not?

Dec 23 '06 #8

P: n/a
Noah Roberts wrote:
>
Stefan Naewe wrote:
White Wolf schrieb:
However there is another "rule" you break: do not use std::pair
for your own types. Use them as members, or private inheritance,
but not directly as a user defined type.
Why not ?

bump...
"Bump"? What does that mean?

Brian
Dec 23 '06 #9

P: n/a
Noah Roberts wrote:
Stefan Naewe wrote:
>White Wolf schrieb:
>>However there is another "rule" you break: do not use std::pair
for your own types. Use them as members, or private inheritance,
but not directly as a user defined type.

Why not ?

bump...

yeah, why not?
Because std::pair isn't a user defined type? :-)

One problem in particular is that it doesn't have operator>and operator<<
defined, and you are formally not allowed to define those inside namespace
std. :-)))

Bo Persson
Dec 24 '06 #10

P: n/a

Bo Persson wrote:
Noah Roberts wrote:
Stefan Naewe wrote:
White Wolf schrieb:

However there is another "rule" you break: do not use std::pair
for your own types. Use them as members, or private inheritance,
but not directly as a user defined type.

Why not ?
bump...

yeah, why not?

Because std::pair isn't a user defined type? :-)

One problem in particular is that it doesn't have operator>and operator<<
defined, and you are formally not allowed to define those inside namespace
std. :-)))
You can't define operator >for pair outside namespace std because you
can't use pair for your own types because you formally can't define
operator >inside of std??

Oh well. Either it's a bug in MS C++ and it's perfectly ok to define
an operator >for pair outside of namespace std or both G++ and Comeau
are the ones that are broken. Since nobody seems to have a clear idea
why it shouldn't be perfectly ok my money is on MS being wrong, again.

Dec 25 '06 #11

P: n/a
Noah Roberts wrote:
Bo Persson wrote:
>Noah Roberts wrote:
>>Stefan Naewe wrote:
White Wolf schrieb:

However there is another "rule" you break: do not use std::pair
for your own types. Use them as members, or private
inheritance, but not directly as a user defined type.

Why not ?

bump...

yeah, why not?

Because std::pair isn't a user defined type? :-)

One problem in particular is that it doesn't have operator>and
operator<< defined, and you are formally not allowed to define
those inside namespace std. :-)))

You can't define operator >for pair outside namespace std because
you can't use pair for your own types because you formally can't
define operator >inside of std??

Oh well. Either it's a bug in MS C++ and it's perfectly ok to
define an operator >for pair outside of namespace std or both G++
and Comeau are the ones that are broken. Since nobody seems to
have a clear idea why it shouldn't be perfectly ok my money is on
MS being wrong, again.
It is perfectly legal to define operator>for std::pair outside of
namespace std. It just doesn't always work, because name lookup sometimes
doesn't find it.

We are not allowed to add overloads inside namespace std, because there is a
blanket statement banning this (17.4.3.1). It says that we are allowed to
add specializations that depend on user defined names, but nothing else.
This allows the implementation to have any number of overloads as an
implementation detail.

The catch 22 for std::pair is that we know that standard doesn't specify any
operator>overload for it. If it did, we wouldn't have any problems! So, in
practice it is almost certain that we could add an overload to namespace
std, *except* for the fact that the standard explicitly says that we cannot
("undefined behavior").
Bo Persson
Dec 25 '06 #12

This discussion thread is closed

Replies have been disabled for this discussion.