Объект функции С++ для возврата `p-> first` и` p-> second`

Есть ли встроенный объект функции, который возвращает p->first и p->second, так что я могу с радостью написать

transform(m.begin(),m.end(),back_inserter(keys),get_first);
transform(m.begin(),m.end(),back_inserter(vals),get_second);

Решение на основе STL является лучшим, решение boost является вторым по эффективности.

Да, я знаю boost::lambda, я не хочу его использовать.

Ответ 1

Существуют нестандартные расширения для g++ и SGI называется select1st и select2nd. Поэтому в STL ничего не может быть.

Boost bind также может это сделать, дать ему указатель на правильную функцию-член

boost::bind(&std::map<string,string>::value_type::second,_1)

Ответ 2

Мы можем легко написать select1st и select2nd:

struct select1st
{
   template< typename K, typename V >
   const K& operator()( std::pair<K,V> const& p ) const
   {
       return p.first;
   }
};

struct select2nd
{
   template< typename K, typename V >
   const V& operator()( std::pair<K,V> const& p ) const
   {
       return p.second;
   }
};

Вот альтернатива, на самом деле более гибкая версия:

struct select1st
{
   template< typename P >
   typename P::first_type const& operator()( P const& p ) const
   {
       return p.first;
   }
};

struct select2nd
{
   template< typename P >
   typename P::second_type const& operator()( P const& p ) const
   {
       return p.second;
   }
};

затем:

transform(m.begin(),m.end(),back_inserter(keys), select1st());
transform(m.begin(),m.end(),back_inserter(vals), select2nd());

Ответ 3

Если вы можете использовать С++ 0x, вы можете использовать реальные lambdas с g++ 4.5, или вы можете использовать новую библиотеку tuple, которая полностью совместима с парами std::. Затем вы можете использовать std:: get < 0 > для first и std:: get < 1 > для второго.

Если вы привязаны к С++ 98, вы можете использовать std:: tr1:: tuple вместо std:: pair, так как в TR1 get не работает с std:: pair.

Также вы можете использовать bind из TR1 (tr1/functional), как описано в Elazar.