Re: Correct swapping
Diego Martins schrieb:
It is not my intention hijacking this thread, but please, take a look
into this code snippet:
#include <fstream>
#include <iterator>
namespace std {
ostream & operator<<(ostream & os, const Histogram::Map::value_type
&
pair) { return os << pair.first << ' ' << pair.second; }
}
Strictly speaking, providing this definition in namespace std causes
undefined behaviour according to 17.4.3.1/1.
void save(const char * filename, const Histogram::Map & data)
{
std::ofstream file(filename);
std::copy(data.begin(),data.end(),std::ostream_iterator<Histogram::Map::valu
e_type>(file,"\n"));
}
I have to declare ostream & operator<<() into the namespace std or
else std::copy() won't work
For me, this is an ugly workaround. Is Falk's method described above
more acceptable to "fix" my code?
I think you have a design problem. From your snippet not
all necessary information is available, but I assume that
Histogram::Map is a typedef for some std::map<X, Y>.
The problem occurs, if X and Y are non-user-defined types
in global namespace, because ADL will not find them.
Otherwise there exists no technical problems with your
example. Basically, all operations belonging to a type should
be in the same namespace, where this type is defined. This
would allow ADL to find your operator<<. Because the value_type
of the map is some std::pair, it's natural, that only a
corresponding operator<< in ns std is found in this case.
But even if std::pair itself belongs to ns std, ADL would
find the corresponding operator<< overloads for X and Y,
rpovided these where UD types.
Another point to consider is, that it's usually a bad idea, to
provide operator<< on some arbitrary std::pair, because neither
std::pair nor std::ostream are *your* types. To fix your problem
I recommend in this special situation to use one of the following:
(a) Replace your std::copy invocation by a std::for_each call
(which uses a special print functor and *not* operator<< on
std::pair) or an explicit loop.
(b) Use a better customizable iterator like boost::transform_iterator
which uses the in (a) mentioned print-functor. This ansatz is
nearly identical to your std::copy approach, where you simply
replace std::ostream_iterator by boost::transform_iterator.
Otherwise you contaminate the global namespace with operators
that can have unexpected effects for other clients of your code.
Greetings from Bremen,
Daniel Kr?gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]