Re: How to copy maps to ostream_iterators?
"Siegfried Heintze" <siegfried@heintze.com> writes:
I have the following code that I am trying to compile with g++ 3.2
(see below).
The syntax error messages are telling me there is no function
operator<< defined to accept a std::pair.
Syntax errors? I'd expect to see something like "no match". The syntax
seems ok, though.
This is not true: as you can see I have defined such a function.
But not in the right namespace. Argument dependent lookup causes it to
be looked up in namespace std; and only there, because some overloads
of operator<< are found there.
I've seen this work with other compilers. I've tried
std::ostream& operator<<(std::ostream&os, const
std::pair<std::string,std::string>&x){ .... }
but that does not work either.
Can anyone tell me what I am doing wrong?
Thanks,
Siegfried
template <typename K, typename V>
inline std::ostream& operator<<(std::ostream& os, const std::pair<K,V>& x)
{
return os << "[" << x.first << ","<< x.second << "]";
}
std::map<std::string,std::string> m;
std::string hello="hello", world="world";
m[hello]=world;
std::copy(m.begin(),m.end(),
std::ostream_iterator<std::pair<std::string,std::string> >(std::cout));
The value_type of this map type is
std::pair<std::string const, std::string>, which is different from the
type you use.
The following program compiles:
#include <map>
#include <algorithm>
#include <iostream>
#include <ostream>
#include <iterator>
namespace std
{
template <typename K, typename V>
inline std::ostream& operator<<(std::ostream& os, std::pair<K,V> const & x)
{
return os << "[" << x.first << "," << x.second << "]";
}
}
int main()
{
typedef std::map<std::string,std::string> map_type;
map_type m;
std::string hello("hello");
std::string world("world");
m[hello] = world;
std::copy(m.begin(),m.end(),
std::ostream_iterator<map_type::value_type>(std::cout));
}
The problem is that strictly speaking, it has undefined behavior,
because we mere users are not allowed to do anything in namespace std
other than provide specializations of Standard templates for our own
types.
What about
#include <map>
#include <algorithm>
#include <iostream>
#include <ostream>
#include <iterator>
template <typename pair_type>
struct pair_printer
{
void operator()(pair_type const & x)
{
std::cout << "[" << x.first << ","<< x.second << "]";
}
};
int main()
{
typedef std::map<std::string,std::string> map_type;
map_type m;
std::string hello("hello");
std::string world("world");
m[hello] = world;
std::for_each(m.begin(),m.end(),
pair_printer<map_type::value_type>());
}
?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]