I am looking for a generic, reusable way to shuffle a std::vector
in C++. This is how I currently do it, but I think it's not very efficient because it needs an intermediate array and it needs to know the item type (DeckCard in this example):
srand(time(NULL));
cards_.clear();
while (temp.size() > 0) {
int idx = rand() % temp.size();
DeckCard* card = temp[idx];
cards_.push_back(card);
temp.erase(temp.begin() + idx);
}
Since C++20, we have
#include <algorithm>
#include <random>
auto rng = std::default_random_engine {};
std::ranges::shuffle(cards_, rng);
For C++11 to C++17, it's slightly more verbose:
#include <algorithm>
#include <random>
auto rng = std::default_random_engine {};
std::shuffle(std::begin(cards_), std::end(cards_), rng);
Make sure to reuse the same instance of rng
throughout multiple calls to std::shuffle
if you intend to generate different permutations every time!
Moreover, if you want your program to create different sequences of shuffles each time it is run, you can seed the constructor of the random engine with the output of std::random_device
:
auto rd = std::random_device {};
auto rng = std::default_random_engine { rd() };
If you're stuck with C++98, you may use:
#include <algorithm>
std::random_shuffle(cards_.begin(), cards_.end());
Avoid this for new code, though: std::random_shuffle()
was removed in C++20.