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