educative.io

Educative

Std::transform doesn't behave same for some container

Suppose I have a vector v{1,2,3,4,5}

If I want to insert it to another vector (say v1), I can do something like this;

std::transform(v.begin(), v.end(), v1.begin(), [](const auto& val) { return val+1; });

But If I want to insert all values to a set/unordered_set, just specifying the begin() iterator won’t work

I have to use std::inserter() as following
std::transform(v.begin(), v.end(), std::inserter(my_set, my_set.begin()), [](const auto& val) { return val+1;});

Could you any one help me, what I’m missing? Shouldn’t std::transform also insert val in set as we have its begin() iteratior? [I have also initialized the set with enough size]

HI @Pankaj_Singh

Kindly provide the complete code. Before that, you can also follow the below approach.

Initializing a set with a vector during its construction is easy:

std::set<int> fooSet(fooVec.begin(), fooVec.end());

Inserting the elements of a vector into an already existing set takes a bit more machinery:

std::copy(fooVec.begin(), fooVec.end(), std::inserter(fooSet, fooSet.end()));

std::copy should be familiar. It inserts the elements of a source container into a destination container. However, it requires the destination container to have enough space for the copied elements. To get around this hassle, the typical solution is to use insert iterators . The commonly used std::back_inserter and std::front_inserter do not work on sets. So, we resort to the std::inserter . But, this requires a position as the second parameter. Thankfully, for associative containers like sets, the second parameter is only a hint, so we can pass any position (like fooSet.end() or fooSet.end()).

1 Like