std::copy to std::cout for std::pair

前端 未结 10 558
耶瑟儿~
耶瑟儿~ 2020-12-04 20:08

I have next code:

#include 
#include 
#include 
#include 

//namespace std
//{

std::ostream&         


        
相关标签:
10条回答
  • 2020-12-04 20:44
     for_each(some_map.begin(), some_map.end(), [](const std::map < size_t, size_t >::value_type &ite){
                 cout<<ite.first<<" "<<ite.second<<endl;
    
    }); 
    

    --- It is fine with C++11

    0 讨论(0)
  • 2020-12-04 20:45

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

    0 讨论(0)
  • 2020-12-04 20:51

    [I'd rather delete this answer, but I'll leave it for now, in case someone finds the discussion interesting.]

    Since it's a reasonable extension to the std library, I'd just put it in std namespace, especially if this is a one time thing. You can just declare it static to prevent it from causing linker errors, should someone else do the same thing someplace else.

    Another solution that comes to mind is to create a wrapper for std::pair:

    template<class A, class B>
    struct pairWrapper {
      const std::pair<A,B> & x;
      pairWrapper(const std::pair<A,B> & x) : x(x) {}
    }
    
    template<class A,class B>
    std::ostream & operator<<(std::ostream & stream, const pairWrapper<A,B> & pw) { ... }
    
    0 讨论(0)
  • 2020-12-04 20:52

    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.

    0 讨论(0)
  • 2020-12-04 21:01

    Using Boost Lambda, you could try something like this. The version I have of Boost Lambda, this doesn't actually work, I'll test and fix later.

    #include <boost/lambda/lambda.hpp>
    #include <boost/lambda/bind.hpp>
    
    using namespace boost::lambda;
    
    std::for_each( some_map.begin(), some_map.end(), 
                   std::cout << bind( &std::map<size_t,size_t>::value_type::first, _1 )
                             << ","
                             << bind( &std::map<size_t,size_t>::value_type::second, _1 ) );
    
    0 讨论(0)
  • 2020-12-04 21:04

    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));
    
    0 讨论(0)
提交回复
热议问题