2015-11-04 2 views
0

Я ищу, чтобы вставить значения в std :: vector таким образом, как std :: transform. std :: transform требует предварительно заданного третьего аргумента, но в моем случае размер зависит от transformers() и не предсказуем.Замена std :: transform, вставка в std :: vector

... 
// std::vector<int> new_args(); <-- not working 
std::vector<int> new_args(args.size()); 
std::transform(args.begin(),args.end(),new_args.begin(),transformers()); 

Есть ли способ std: transform-ish вставлять значения в std :: vector?

+0

[Это] (http://en.cppreference.com/w/cpp/iterator/back_inserter) может помочь –

+3

Какого образом размера зависит от 'transformers'? Вы делаете какую-то фильтрацию? Если да, то откуда вы узнали, что что-то было отфильтровано? Просьба уточнить. –

+0

'std :: vector new_args();' объявляет функцию (самый неприятный синтаксический анализ), она должна быть 'std :: vector new_args;' или 'std :: vector new_args {};'. (тогда 'std :: back_inserter' для вашей реальной проблемы). – Jarod42

ответ

2

Вы можете использовать std::back_inserter, который использует .push_back для добавления значений вектора:

std::vector<int> new_args; 
std::transform(args.begin(),args.end(),std::back_inserter(new_args),transformers()); 

КСТАТИ: std::vector<int> new_args(); это объявление функции. Вы можете создать пустой std::vector с std::vector<int> new_args;

4

Вам не нужно предварительно задавать вектор, который будет заполнен преобразованием. Использование std::back_inserter Оно будет действовать как итератор к вектору, но на самом деле вызовет push_back(), чтобы вставить элементы в вектор.

Таким образом, вы код будет выглядеть

std::vector<int> new_args; 
std::transform(args.begin(),args.end(),std::back_inserter(new_args),transformers()); 
+0

'Вам не нужно предварительно задавать вектор, который будет заполнен преобразованием', как это сделать? Если я хочу push_back 50000 элементов, я хотел бы это зарезервировать. –

+0

@Lorac 'back_inserter' работает, вызывая' push_back', поэтому при необходимости он будет изменять размер вектора. Если вы этого не хотите, тогда вам нужно вызвать 'reserve' после того, как вы по умолчанию сконструируете вектор. – NathanOliver

0

Слава богу, есть подталкивание :: диапазон.

Поскольку ввод и вывод отличается по размеру и типу, std :: copy_if и std :: transform не помогли.

#include <boost/range/adaptor/filtered.hpp> 
#include <boost/range/adaptor/transformed.hpp> 
#include <boost/range/algorithm_ext/push_back.hpp> 
#include <iostream> 
#include <vector> 
#include <string> 
#include <cmath> 

struct is_even 
{ 
    bool operator()(int x) const {return x%2==0;} 
}; 

struct to_square_root 
{ 
    float operator()(int x) const {return std::sqrt(x);} 
}; 

int main(int argc, const char* argv[]) 
{ 
    std::vector<int> input={1,2,3,4,5,6,7,8,9}; 
    std::vector<float> output; 

    boost::push_back (
     output 
     , input 
     | boost::adaptors::filtered(is_even()) 
     | boost::adaptors::transformed(to_square_root()) 
    ); 

    for(auto i: output) std::cout << i << "\n"; 
}