-1

When using algorithms with output iterator such as std::set_difference, or std::transform, is there any simple way of overwriting the original vector?

vector<int> v { 0, 1, 2, 3 };
vector<int> v2{ 1, 3 };

std::set_difference(v.begin(), v.end(), v2.begin(), v2.end(), v.begin());

v = { 0, 2, 2, 3}

In this specific case I can probably do something like:

auto it = std::set_difference(v.begin(), v.end(), v2.begin(), v2.end(), v.begin());
v.resize(std::distance(v.begin(), it));

v = { 0, 2 }

But it looks like a hassle, it's not very readable, and it only works if a destination <= to source in size.

Is there a modular way to go about this?

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
Kostas
  • 4,061
  • 1
  • 14
  • 32
  • 1
    With `std::transform` or other functions that doesn't change the size of the involved container, it's not a problem. Otherwise you just have to live with the "hassle". – Some programmer dude Oct 27 '18 at 19:22
  • @Someprogrammerdude What about when the destination is larger in size? – Kostas Oct 27 '18 at 19:29
  • That's a bit more problematic, and can only be solved by using a different (temporary) container. – Some programmer dude Oct 27 '18 at 19:30
  • This isn't a valid use of [`set_difference`](https://en.cppreference.com/w/cpp/algorithm/set_difference). From the standard: "The resulting range shall not overlap with either of the original ranges." – 1201ProgramAlarm Oct 27 '18 at 20:04

1 Answers1

0

set_difference requires that the output range does not overlap with either of the input ranges.

You have to build the difference into a new vector. Then you can swap that result back into the original vector.

vector<int> result;
std::set_difference(v.begin(), v.end(), v2.begin(), v2.end(), std::back_inserter(result));
std::swap(v, result);
1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
  • I believe using `result.begin()` instead of `std::back_inserter(result)` gives [UB](https://stackoverflow.com/questions/27215748/what-happens-if-i-use-vectorbegin-instead-of-stdback-insertervector-for). Also, does swap use move semantics? – Kostas Oct 27 '18 at 20:29
  • @GillBates Good point on `back_inserter`. Otherwise the result would have to have enough elements in it to hold the difference. Swap will use move semantics, and for vectors (with the same allocator) will swap the internal data pointers and not move any of the elements. – 1201ProgramAlarm Oct 27 '18 at 20:33