23

In my code I have a std::unordered_set and I need to move the data into a std::vector. I'm using the std::unordered_set while getting the data to ensure only unique values are stored prior to converting to a std::vector. My question is how do I move the contents to the std::vector the most efficiently? I don't need the std::unordered_set after the data is moved. I currently have the following:

std::copy(set.begin(), set.end(), std::back_inserter(vector));
nalyd88
  • 4,940
  • 8
  • 35
  • 51
  • 4
    Surely `std::vector::reserve` would help (if you're not doing that already). – LogicStuff Feb 28 '17 at 22:29
  • What, exactly, is your data? – Yakk - Adam Nevraumont Feb 28 '17 at 22:31
  • It's numeric values. `std::vector` – nalyd88 Feb 28 '17 at 22:32
  • 2
    For `double`, copy is as efficient as move, but you should reserve as LogicStuff recommends. Separately, if in your case it takes time for the data to arrive (e.g. over the network, from a huge file doing async I/O etc) and you don't actually need the vector sorted, you could check whether it's the first time you've seen a value as you attempt insertion to the set, and if so also insert to the vector so it's ready to use as soon as the last input's received (though this works best if you know the number of elements to reserve beforehand). – Tony Delroy Feb 28 '17 at 22:41
  • Do you consider two double same if they are "nearly equal"? The default hashing maybe not enough in some cases. http://stackoverflow.com/questions/14943817/does-stdhash-guarantee-equal-hashes-for-equal-floating-point-numbers – Petar Petrovic Mar 01 '17 at 04:26

1 Answers1

34

Before C++17, the best you can do is:

vector.insert(vector.end(), set.begin(), set.end());

The set's elements are const, so you can't move from them - moving is just copying.


After C++17, we get extract():

vector.reserve(set.size());
for (auto it = set.begin(); it != set.end(); ) {
    vector.push_back(std::move(set.extract(it++).value()));
}

Although given your comment that your data is doubles, this wouldn't matter.

Barry
  • 286,269
  • 29
  • 621
  • 977