Since C++11, std::shuffle()
takes an rvalue reference to a random bit generator:
template<class RandomIt, class URBG>
void shuffle(RandomIt first, RandomIt last, URBG&& g);
And so I might call it thus:
std::vector<int> v = {...};
std::random_device rd;
std::mt19937 g(rd());
std::shuffle(v.begin(), v.end(), g);
This reveals an error in my understanding of C++ that I haven't been able to satisfy through reading this morning: what is gained by using an rvalue reference here? In other words, why is this not
template<class RandomIt, class URBG>
void shuffle(RandomIt first, RandomIt last, URBG& g);
This is a forwarding reference, not an rvalue reference. They have superficially similar syntax but can be differentiated by the base type being a deduced template parameter.
Your suggested alternative would not compile if an rvalue was given for the third argument, whereas the forwarding reference allows any value category of argument.
Using the cppreference example, it means you have both options of:
std::mt19937 g(rd());
std::shuffle(v.begin(), v.end(), g);
and
std::shuffle(v.begin(), v.end(), std::mt19937(rd()));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With