operator >> needs to be in namespace std??

N

Noah Roberts

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?
 
S

Steven T. Hatton

Noah said:
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::eek:perator>>(...) might be.
 
G

Gianni Mariani

Noah said:
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.
 
S

Steven T. Hatton

Gianni said:
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::eek:stream& operator<<(std::eek:stream& out, std::pair<T,T>& p) {
return out << p.first << p.second;
}


int main() {
std::pair<int,int> p(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.
 
N

Noah Roberts

Gianni said:
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
 
W

White Wolf

Noah said:
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

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.
 
B

Bo Persson

Noah said:
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
 
N

Noah Roberts

Bo said:
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.
 
B

Bo Persson

Noah said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,900
Latest member
Nell636132

Latest Threads

Top