Is there a standard C++ function object for taking apart a std::pair?

前端 未结 6 1577
粉色の甜心
粉色の甜心 2020-12-20 14:06

Does anyone know if there\'s a de-facto standard (i.e., TR1 or Boost) C++ function object for accessing the elements of a std::pair? Twice in the past 24 hours I\'ve wished

相关标签:
6条回答
  • 2020-12-20 14:22

    One option that wasn't suggested is std::tr1::get. See sections 6.1.2 and 6.1.4 of n1745.

    std::pair< std::string, int > p( "foo", 1729 );
    
    int hr = std::tr1::get< 1 >( p );
    

    Definitely not as easy to use as bind in the map extraction case you mentioned but still worth knowing about. Adapting Johannes' code:

    typedef std::map<std::string, int> map_type;
    
    std::vector<int> values; // will contain all values
    map_type map;
    
    // std::tr1::get is overloaded so we need to help the compiler choose
    const map_type::value_type::second_type & (*get)( const map_type::value_type & ) =
      &std::tr1::get< 1, map_type::value_type::first_type, map_type::value_type::second_type >;
    
    std::transform(map.begin(), 
                   map.end(), 
                   std::back_inserter(values), 
                   get);
    
    0 讨论(0)
  • 2020-12-20 14:25

    Take a look at boost::adaptors. There are predefined adaptors for iterating over map keys or values without copying them to an intermediate container.

    0 讨论(0)
  • 2020-12-20 14:33

    From the way you worded your question, I'm not sure this is a proper response, but try boost::tie (part of the Boost::tuple library). It works on std::pairs too.

    0 讨论(0)
  • 2020-12-20 14:36

    boost::bind is what you look for.

    boost::bind(&std::pair::second, _1); // returns the value of a pair
    

    Example:

    typedef std::map<std::string, int> map_type;
    
    std::vector<int> values; // will contain all values
    map_type map;
    std::transform(map.begin(), 
                   map.end(), 
                   std::back_inserter(values), 
                   boost::bind(&map_type::value_type::second, _1));
    
    0 讨论(0)
  • 2020-12-20 14:36

    boost::bind is often used to adapt std::map containers for use with algorithms. Here is an example:

    void print_string(const std::string& s) {
      std::cout << s << '\n';
    }
    
    
    std::map<int,std::string> my_map;
    my_map[0]="Boost";
    my_map[1]="Bind";
    
    
    std::for_each(my_map.begin(), my_map.end(),
                  boost::bind(&print_string, boost::bind(
                  &std::map<int,std::string>::value_type::second,_1)));
    
    0 讨论(0)
  • 2020-12-20 14:46

    What about using combinations of different containers.

    For example when I wanted to partition a vector into items contained in a supplemental map and items that where not contained in the supplemental map I used the following:

    typedef int DWORD; 
    typedef std::pair<std::string, bool> user_info; 
    typedef std::map<DWORD, user_info> USER_MAP; 
    typedef std::vector<DWORD> VEC_STAFF; 
    
    VEC_STAFF::iterator it = std::partition(Staff.begin(), Staff.end(), (bind(&USER_MAP::find, m_Users, _1) != m_Users.end()));
    

    Now I have a second problem - during the running of the application the status bool of user_info can change, and later on I want to re-partition the vector with items that have a status bool of true rather than just being contained in the supplemental map.

    However I seem to have a problem accessing the second item of a nested pair.

    I tried the following but I cannot seem to access the nested pair!

    CActiveUsers::VEC_STAFF::const_iterator itCurEnd = partition(Staff.begin(), Staff.end(), bind(&USER_MAP::value_type::second::second, bind(&USER_MAP::find, &m_Users, _1)) == true); 
    
    0 讨论(0)
提交回复
热议问题