user1587451
user1587451

Reputation: 1008

Replacing std::transform, inserting into a std::vector

I'm looking to insert values into a std::vector in a way like std::transform. std::transform needs a pre-sized third argument, but in my case, the size depends on transformers() and is not predictable.

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

Is there a std:transform-ish way to insert values into a std::vector?

Upvotes: 1

Views: 10014

Answers (3)

NathanOliver
NathanOliver

Reputation: 180490

You do not need to pre size the vector that is going to be filled with transform. Using a std::back_inserter It will act like an iterator to the vector but will actually call push_back() to insert the elements into the vector.

So you code would look like

std::vector<int> new_args;
new_args.reserve(args.size); // use this so you don't have grow the vector geometrically.
std::transform(args.begin(),args.end(),std::back_inserter(new_args),transformers());

Upvotes: 7

user1587451
user1587451

Reputation: 1008

Thank god, there's boost::range.

As input and output differs in size and type, std::copy_if and std::transform did not help.

#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";
}

Upvotes: 1

milleniumbug
milleniumbug

Reputation: 15814

You can use std::back_inserter which uses .push_back to add values to the vector:

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

BTW: std::vector<int> new_args(); is a function declaration. You can create an empty std::vector with std::vector<int> new_args;

Upvotes: 3

Related Questions