Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does std::shuffle take an rvalue reference?

Tags:

c++

c++11

rvalue

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);
like image 363
jma Avatar asked Jun 18 '18 05:06

jma


1 Answers

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()));
like image 109
M.M Avatar answered Nov 04 '22 09:11

M.M