KorbenDose
KorbenDose

Reputation: 1263

std::transform with std::istream_iterator

Say I have a string containing numbers separated by empty spaces. I want to insert the numbers into a vector of integers, where every number is decreased by one. So for example:

"1 2 3 4" -> {0, 1, 2, 3}

Now the plan was to use std::transform in combination with a std::istream_iterator<int>, which looks like the following:

std::istringstream source{"1 2 3 4"};
std::vector<int> target;

std::transform(std::istream_iterator<int>(source),
               std::istream_iterator<int>(),
               std::begin(target),
               [](int a) {
                 return a-1;
               }
);

Unfortunately, this doesn't work because std::transform expects target to already be of the right size. So I have to do

std::vector<int> target(4);

Now I have two questions. How can I dynamically find the right size for target beforehand? Is there a more elegant way to achieve the actual goal?

Upvotes: 1

Views: 780

Answers (1)

KorbenDose
KorbenDose

Reputation: 1263

While researching for this question, I found a simple solution. Simply use std::back_inserter as output iterator instead of std::begin(target).

std::transform(std::istream_iterator<int>(source),
               std::istream_iterator<int>(),
               std::back_inserter(target),
               [](int a) {
                 return a-1;
               }
);

Another solution uses std::for_each:

std::for_each(std::istream_iterator<int>(source),
              std::istream_iterator<int>(),
              [&target](int a) {
                target.push_back(a-1);
              }
);

Upvotes: 4

Related Questions