Home > Net >  Why can't I use a set as the output collection of transform operation on a vector?
Why can't I use a set as the output collection of transform operation on a vector?

Time:03-08

When I use transform on a set and use a vector to store the output, it works fine. But it doesn't seem to work the other way around.

This is the code that doesn't work:

#include <iostream>
#include <vector>
#include <set>
#include <algorithm>

using namespace std;

int multiply(int a) {
    return a * 2;
}
void print(int i) {
    cout << i << " ";
}
int main() {
    int mynumbers[] = { 3,9,2,4,1 };
    vector<int> v1(mynumbers, mynumbers   5);
    set<int> s1(mynumbers, mynumbers   5);
    transform(v1.begin(), v1.end(), s1.begin(), multiply);
    for_each(v1.begin(), v1.end(), print);
    cout << endl;
    for_each(s1.begin(), s1.end(), print);
}

CodePudding user response:

As @molbdnilo pointed out:

The elements of a set are immutable.

Thus, existing elements cannot be overwritten.

However, it can be done with e.g. a std::insert_iterator:

#include <algorithm>
#include <iostream> 
#include <set>
#include <vector>

int main()
{
   std::vector<int> v = { 1, 2, 3, 4, 5 };
   std::set<int> s;
   std::transform(v.begin(), v.end(),
     std::insert_iterator<std::set<int>>(s, s.begin()),
     [](int x) { return x * 2; });
   for (int x : s) std::cout << ' ' << x;
}

Output:

 2 4 6 8 10

Live demo on coliru

CodePudding user response:

As @JeJo already mentioned, std::inserter can be used. Just pasting here the code with it.

set<int> s1;
transform(v1.begin(), v1.end(), inserter(s1, s1.begin()), multiply);

For the testing purpose, it does not matter, although it is not good to initialize the set s1 with vector v1 values, because transform adds/overwrites entries in the target container, and in your code the new values are getting mixed with old values (e.g. 4,9)

  •  Tags:  
  • c
  • Related