问题
According to the cppreference.com reference site on std::shufle, the following method is being deprecated in c++14:
template< class RandomIt >
void random_shuffle( RandomIt first, RandomIt last );
Why will we no longer be able to call the following function without passing a third parameter?
std::random_shuffle(v.begin(),v.end()); //no longer valid in c++14
It doesn't appear as though a different function deceleration has a default parameter set. What is the reason behind this? Was there some kind of alternative added?
回答1:
std::random_shuffle
may make use, under the hood, of random
C family of functions. These functions use global state for seeds and other state.
So it is being deprecated because shuffle
will do the same, but better. Namely, it uses the new <random>
header from C++11 that doesn't use global state, but its own objects making use of generators, devices and distributions.
回答2:
std::random_shuffle
is (effectively) replaced by std::shuffle
. You do need to pass a third parameter (a random number generator), but in exchange for that you get substantially better definition and (typically) behavior.
std::random_shuffle
was fairly poorly defined. It typically used rand()
to generate the random numbers, but nothing said whether (and if so how) it called srand
, so you couldn't depend (for one example) in rand
being seeded how you wanted (and if you seeded it, you couldn't depend on that being put to use). If memory serves, there was also some confusing (and somewhat self-contradictory) language that could be interpreted as saying that random_shuffle
couldn't use rand
at all, and/or that it couldn't seed it with srand
. Even at best, many implementations of rand()
were quite poor, so even at very best you couldn't depend on useful results.
Bottom line: random_shuffle
is no loss. Use std::shuffle
instead, and your code will be much better for it.
回答3:
We can find the rationale in this document N3775: Deprecating rand and Friends which says:
We therefore now propose to execute the next step of this plan to discourage the use of the traditional C function rand as well as its associated seeding function srand and upper limit macro RAND_MAX.6 In particular, we propose to begin this transition by formally deprecating:
- rand, srand, and RAND_MAX and
- algorithm random_shuffle() (keeping shuffle, however).
The rationale for deprecating random_shuffle() is that one overload is specified so as to depend on rand, while the other overload is specified so as to require a hard-to-produce distribution object from the user; such a distribution is already an implicit part of shuffle, which we retain.
and the later document Discouraging rand() in C++14, v2 which reiterates this position.
Update
As Howard Hinnant notes N3775
has an error: rand_shuffle()
is allowed but not required to use rand()
under the hood but that would not change the rationale.
回答4:
random_shuffle
is being deprecated because its RNG is unspecified -- not just that you don't have to specify it, but that the standard itself doesn't specify it. On VC++, for instance, it uses rand()
, which is implemented really poorly!
来源:https://stackoverflow.com/questions/22600100/why-are-stdshuffle-methods-being-deprecated-in-c14