The [select1st] struct template and its counterpart [select2nd], are function objects that can be used to select the first or second attribute of a pair, respectively. They are both very convenient when using standard algorithms to copy map keys or values into non-associative (i.e. sequence) containers. Unfortunatelly, both of these non-standard algorithm extensions are absent from many, if not all, non-SGI implementations of the STL. So, without further ado, I present these two struct templates for use in your own applications:
#include <functional> template <typename pair_type> struct select1st: public std::unary_function<const pair_type &, typename const pair_type::first_type &> { const typename pair_type::first_type &operator()(const pair_type &v) const { return v.first; } }; template <typename pair_type> struct select2nd: public std::unary_function<const pair_type &, typename const pair_type::second_type &> { const typename pair_type::second_type &operator()(const pair_type &v) const { return v.second; } };
#include <algorithm> #include <boost/assign/list_of.hpp> #include <functional> #include <iostream> #include <map> #include <string> using namespace std; // For brevity in this example // Here are the select1st and select2nd definitions. In a real application, you would want to // include these from some header file that contained these and other like minded definitions template <typename pair_type> struct select1st: public std::unary_function<const pair_type &, typename const pair_type::first_type &> { const typename pair_type::first_type &operator()(const pair_type &v) const { return v.first; } }; template <typename pair_type> struct select2nd: public std::unary_function<const pair_type &, typename const pair_type::second_type &> { const typename pair_type::second_type &operator()(const pair_type &v) const { return v.second; } }; int main() { // Create a map of ordinal values to their names, with three associations typedef map<int,string> IntStringMap; IntStringMap ordinalNamesMap(boost::assign::map_list_of (1,string("1st")) (2,string("2nd")) (3,string("3rd"))); // Display all keys in order transform( ordinalNamesMap.begin(), ordinalNamesMap.end(), ostream_iterator<IntStringMap::key_type>(cout,","), select1st<IntStringMap::value_type>()); cout << '\n'; // Display all values, in key order transform( ordinalNamesMap.begin(), ordinalNamesMap.end(), ostream_iterator<IntStringMap::mapped_type>(cout,","), select2nd<IntStringMap::value_type>()); cout << '\n'; }
1,2,3, 1st,2nd,3rd,