std::copy to std::cout for std::pair
There is no standard way to cout a std::pair
because, well, how you want it printed is probably different from the way the next guy wants it. This is a good use case for a custom functor or a lambda function. You can then pass that as an argument to std::for_each
to do the work.
typedef std::map<size_t, size_t> MyMap;
template <class T>
struct PrintMyMap : public std::unary_function<T, void>
{
std::ostream& os;
PrintMyMap(std::ostream& strm) : os(strm) {}
void operator()(const T& elem) const
{
os << elem.first << ", " << elem.second << "\n";
}
}
To call this functor from your code:
std::for_each(some_map.begin(),
some_map.end(),
PrintMyMap<MyMap::value_type>(std::cout));
I've founded one new elegant way to solve this problem.
I've got many interest ideas when read answers:
- wrap iterator, for transform std::pair to std::string;
- wrap std::pair, for have a chance to overload operator<<(...);
- use usual std::for_each with printing functor;
- use std::for_each with boost::labda - looks nice, except accessing to std::pair< >::first and std::pair< >::second members;
I think I will use all of this ideas in future for solve different other problems.
But for this case I've understaded that I can formulate my bproblem as "transform map's data to strings and write them to output stream" instead "copy map's data to ouput stream". My solution looks like:
namespace
{
std::string toString( const std::pair< size_t, size_t >& data)
{
std::ostringstream str;
str << data.first << ", " << data.second;
return str.str();
}
} // namespace anonymous
std::transform(
some_map.begin(),
some_map.end(),
std::ostream_iterator< std::string >( std::cout, "\n" ),
toString );
I think this method is most short and expressive than others.
I'd just like to point out that adding things to the std:: namespace is illegal according to the C++ Standard (see section 17.4.3.1).