 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Wu Yongwei Guest
|
Posted: Mon Oct 24, 2005 12:39 pm Post subject: Problem with namespace and overridden function |
|
|
Anyone thinks the following code reasonable?
--------------------------------------------------------------
#include <algorithm>
#include <iostream>
#include <iterator>
#include <memory>
#include <vector>
typedef std::pair<int, int> MyPair;
std::ostream& operator<<(std::ostream& os, const MyPair& x)
{
os << x.first << ',' << x.second;
return os;
}
int main()
{
std::vector
v.push_back(std::make_pair(0, 1));
v.push_back(std::make_pair(1, 2));
v.push_back(std::make_pair(2, 4));
v.push_back(std::make_pair(3, );
std::copy(v.begin(), v.end(),
std::ostream_iterator<MyPair>(std::cout, "n"));
}
--------------------------------------------------------------
The big problem is that it does not compile on some famous compilers,
unless I wrap std::ostream& operator<<(std::ostream& os, const MyPair&
x) in namespace std (which seems not nice as well). My questions are:
1) Is the rejection standard conformant? (I would assume yes, but I
need a confirmation.)
2) What should be the best way to work around?
Best regards,
Yongwei
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Carl Barron Guest
|
Posted: Mon Oct 24, 2005 4:43 pm Post subject: Re: Problem with namespace and overridden function |
|
|
In article <1130150337.487342.296930 (AT) g43g2000cwa (DOT) googlegroups.com>, Wu
Yongwei <wuyongwei (AT) gmail (DOT) com> wrote:
| Quote: | Anyone thinks the following code reasonable?
--------------------------------------------------------------
#include <algorithm
#include
#include
#include
#include
typedef std::pair
std::ostream& operator<<(std::ostream& os, const MyPair& x)
{
os << x.first << ',' << x.second;
return os;
}
int main()
{
std::vector
v.push_back(std::make_pair(0, 1));
v.push_back(std::make_pair(1, 2));
v.push_back(std::make_pair(2, 4));
v.push_back(std::make_pair(3, );
std::copy(v.begin(), v.end(),
std::ostream_iterator<MyPair>(std::cout, "n"));
}
--------------------------------------------------------------
The big problem is that it does not compile on some famous compilers,
unless I wrap std::ostream& operator<<(std::ostream& os, const MyPair&
x) in namespace std (which seems not nice as well). My questions are:
1) Is the rejection standard conformant? (I would assume yes, but I
need a confirmation.)
2) What should be the best way to work around?
1 - yes |
2 - The easiest is to derive a class from std::pair
struct MyPairOut:std::pair<int,int>
{
MyPairOut(){}
MyPairOut(std::pair<int,int> const &a):std::pair<int,int>(a){}
};
std::ostream & operator << (std::ostream &os,const MyPairOut &x)
{
return os << x.first << ',' << x.second;
}
typedef std::pair
rest of code is the same including the typedef and the
ostream_iterator<MyPair> is changed to ostream_iterator<MyPairOut>.
This avoid unneeded construction except when the look up fails because
of ADL.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Valentin Samko Guest
|
Posted: Mon Oct 24, 2005 9:20 pm Post subject: Re: Problem with namespace and overridden function |
|
|
Carl Barron wrote:
| Quote: | struct MyPairOut:std::pair<int,int
{
MyPairOut(){}
MyPairOut(std::pair
};
std::ostream & operator << (std::ostream &os,const MyPairOut &x)
{
return os << x.first << ',' << x.second;
}
This avoid unneeded construction except when the look up fails because
of ADL.
|
What does it have to do with ADL? I do not see where ADL would kick in,
as all the
arguments, as well as the function where you use operator << are in the
std namespace, so
it ends with unqualified name lookup. It does not see operator << in the
global namespace
as it is shadowed by overloads of this operator in the std namespace.
Unfortunately the standard does not allow overloading functions in the
std namespace.
There is a proposal to fix this - N1252.
--
Valentin Samko - http://val.samko.info
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Carl Barron Guest
|
Posted: Tue Oct 25, 2005 12:49 pm Post subject: Re: Problem with namespace and overridden function |
|
|
In article <435d1abd$0$94257$892e7fe2 (AT) authen (DOT) white.readfreenews.net>,
Valentin Samko <c++.moderated (AT) digiways (DOT) com> wrote:
| Quote: | Carl Barron wrote:
struct MyPairOut:std::pair<int,int
{
MyPairOut(){}
MyPairOut(std::pair
};
std::ostream & operator << (std::ostream &os,const MyPairOut &x)
{
return os << x.first << ',' << x.second;
}
This avoid unneeded construction except when the look up fails because
of ADL.
What does it have to do with ADL? I do not see where ADL would kick in,
as all the
arguments, as well as the function where you use operator << are in the
std namespace, so
it ends with unqualified name lookup. It does not see operator << in the
global namespace
as it is shadowed by overloads of this operator in the std namespace.
Unfortunately the standard does not allow overloading functions in the
std namespace.
There is a proposal to fix this - N1252.
correct, ADL is the original problem as typedef std::pair |
MyPair; does not remove MyPair from namespace std.So ADL is the
original problem. MyPairOut is not in namespace std, and can be used
to avoid ADL problems with operator << () or any other function call
suffering from ADL.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze Guest
|
Posted: Tue Oct 25, 2005 3:56 pm Post subject: Re: Problem with namespace and overridden function |
|
|
Valentin Samko wrote:
| Quote: | Carl Barron wrote:
|
| Quote: | struct MyPairOut:std::pair<int,int
{
MyPairOut(){}
MyPairOut(std::pair
};
|
| Quote: | std::ostream & operator << (std::ostream &os,const MyPairOut &x)
{
return os << x.first << ',' << x.second;
}
|
| Quote: | This avoid unneeded construction except when the look up
fails because of ADL.
|
| Quote: | What does it have to do with ADL? I do not see where ADL
would kick in, as all the arguments, as well as the function
where you use operator << are in the std namespace, so it ends
with unqualified name lookup. It does not see operator << in
the global namespace as it is shadowed by overloads of this
operator in the std namespace.
|
I'm not sure about his precise comment; I don't see what the
look up has to do with construction. But ADL does come into
play here: MyPairOut is in the global namespace, so ADL causes
the compiler to look in the global namespace when resolving the
overload on operator << in the template. Without ADL, it's hard
to say -- it would be a different language. (In early times,
there were no namespaces, and of course, the compiler would have
found the overloaded operator because it would look in the only
place global names could occur.)
| Quote: | Unfortunately the standard does not allow overloading
functions in the std namespace.
|
It does in certain cases. It allows a template specialization
if the declaration depends on a user defined type. Specializing
std::swap is a classic.
The exception doesn't apply here, of course. But it doesn't
matter; you don't want to define an operator<< for something
like std::pair
introducing a user defined type means that the code will work.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Valentin Samko Guest
|
Posted: Tue Oct 25, 2005 6:22 pm Post subject: Re: Problem with namespace and overridden function |
|
|
kanze wrote:
| Quote: | This avoid unneeded construction except when the look up
fails because of ADL.
What does it have to do with ADL? I do not see where ADL
would kick in, as all the arguments, as well as the function
where you use operator << are in the std namespace, so it ends
with unqualified name lookup. It does not see operator << in
the global namespace as it is shadowed by overloads of this
operator in the std namespace.
I'm not sure about his precise comment; I don't see what the
look up has to do with construction. But ADL does come into
play here: MyPairOut is in the global namespace, so ADL causes
the compiler to look in the global namespace when resolving the
overload on operator << in the template.
|
Yes, ADL can find MyPairOut, but not std::pair<...> . I did not agree with the "when the
lookup fails because of ADL" bit, as ADL does not stop us from finding the right
operator<<, it is just not smart enough to find the operator.
| Quote: | Unfortunately the standard does not allow overloading
functions in the std namespace.
It does in certain cases. It allows a template specialization
if the declaration depends on a user defined type. Specializing
std::swap is a classic.
|
It allows specialisation (17.4.3.1), but not overloading.
--
Valentin Samko - http://val.samko.info
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|