Home > other >  Vector passed by reference inside lambda cannot be modified even if mutable keyword is used
Vector passed by reference inside lambda cannot be modified even if mutable keyword is used

Time:08-09

I am trying to populate a vector with integer values which are coming in from standard input as follows:

std::vector<int> v;

for_each(v.begin(),v.end(),([&](auto &i) mutable {cin>>i; v.push_back(i);}));

However, this statement is not working and the vector does not get filled with incoming values. Can you please suggest where I am going wrong? Thanks

CodePudding user response:

for_each iterates over v and operates on each of its elements. Since v is default-initialized, its size is empty, which means that for_each doesn't do anything.

You might want to use istream_iterator

std::vector<int> v;
std::for_each(std::istream_iterator<int>(std::cin),
              std::istream_iterator<int>(),
              [&](auto i) { v.push_back(i); });
// Or
std::copy(std::istream_iterator<int>(std::cin),
          std::istream_iterator<int>(),
          std::back_inserter(v));

which will read successive integers from std::cin and insert them into v.

CodePudding user response:

std::for_each applies the function object (the lambda) on each element in the passed container. Therefore to the parameter passed to the lambda is the current elements in the vector however, your vector is empty so there's nothing to iterate over so it never runs. You are also trying to assign the value from std::cin to the element in the vector i and then push a reference to that element again to the back of the vector along with the already existing element.

So first of all, if you want to use std::for_each you need to pre-allocate the vectors memory so it has something to iterate over.

std::vector<int> v(5); ///< allocates space for 5 ints

You then can then run std::for_each and std::cin into the lambda's input parameter which is a iterator to the vector, saving the inputs to the vector.

std::vector<int> v(5);

std::for_each(v.begin(), v.end(), [](auto& i) { std::cin >> i; });

The benefit of this solution is that it will automatically terminate reading values once it has finished iterating through the vector, only reading the desired amount of values.

Links and Resources

  • Related