Копировать вектор значений в вектор пар в одну строку - PullRequest
1 голос
/ 28 апреля 2010

У меня есть следующие типы:

struct X { int x; X( int val ) : x(val) {} };
struct X2 { int x2; X2() : x2() {} };

typedef std::pair<X, X2>      pair_t;
typedef std::vector<pair_t>   pairs_vec_t;
typedef std::vector<X>        X_vec_t;

Мне нужно инициализировать экземпляр pairs_vec_t со значениями от X_vec_t.Я использую следующий код, и он работает как положено:

int main()
{
  pairs_vec_t ps;
  X_vec_t xs; // this is not empty in the production code

  ps.reserve( xs.size() );

  { // I want to change this block to one line code.
    struct get_pair {
      pair_t operator()( const X& value ) { 
        return std::make_pair( value, X2() ); }
    };
    std::transform( xs.begin(), xs.end(), back_inserter(ps), get_pair() );
  }

  return 0;
}

Я пытаюсь уменьшить блок копирования до одной строки с помощью boost::bind.Этот код не работает:

for_each( xs.begin(), xs.end(), boost::bind( &pairs_vec_t::push_back, ps, boost::bind( &std::make_pair, _1, X2() ) ) );

Я знаю, почему он не работает , но я хочу знать, как заставить его работать без объявления дополнительных функций и структур?

Ответы [ 3 ]

5 голосов
/ 29 апреля 2010

как то так?

using boost::lambda;
X2 x;
transform(..., (bind(std::make_pair<X,X2>, _1, ref(x))));

Я не могу проверить в данный момент, но если правильно вызвать из памяти, вышеупомянутое действует.

3 голосов
/ 29 апреля 2010
std::for_each( xs.begin(), xs.end(),
               boost::bind( &pairs_vec_t::push_back, &ps,
// you need to pass a pointer —— at least for gcc.   ^ 
                            boost::bind( &std::make_pair<X,X2>, _1, X2() ) ) );
// you need to specify which make_pair to instantiate   ^^^^^^ 
0 голосов
/ 29 апреля 2010

Повышение не требуется.std::bind2nd считается устаревшим в пользу std::bind, принятого в Boost, но на данный момент это стандарт.

pairs_vec_t ps( xs.size() );
transform( xs.begin(), xs.end(), ps.begin(),
    bind2nd( ptr_fun( make_pair<X,X2> ), X2() ) );

Если у вас есть Boost, он более эффективен для insert диапазон (transform_iterator), чем итерация на push_back или предварительный размер:

pairs_vec_t ps(
    make_transform_iterator( xs.begin(), bind2nd( ptr_fun( make_pair<X,X2> ), X2() ) ),
    make_transform_iterator( xs.end(), bind2nd( ptr_fun( make_pair<X,X2> ), X2() ) ) );

Как это для однострочника?

...