web-dev-qa-db-fra.com

Pourquoi les méthodes std :: shuffle sont-elles dépréciées en C ++ 14?

Selon le site de référence cppreference.com sur std :: shufle , la méthode suivante est déconseillée en c ++ 14:

template< class RandomIt >
void random_shuffle( RandomIt first, RandomIt last );

Pourquoi ne pourrons-nous plus appeler la fonction suivante sans passer un troisième paramètre?

std::random_shuffle(v.begin(),v.end()); //no longer valid in c++14

Il ne semble pas que la décélération d'une fonction différente ait un jeu de paramètres par défaut. Quelle est la raison derrière cela? Y a-t-il eu une sorte d'alternative ajoutée?

51
Trevor Hickey

std::random_shufflepeut utiliser, sous le capot, la famille de fonctions random C. Ces fonctions utilisent l'état global pour les graines et les autres états.

Il est donc obsolète car shuffle fera de même, mais en mieux. À savoir, il utilise le nouveau <random> en-tête de C++ 11 qui n'utilise pas l'état global, mais ses propres objets utilisant des générateurs, des périphériques et des distributions.

46
Germán Diago

std::random_shuffle Est (effectivement) remplacé par std::shuffle. Vous devez passer un troisième paramètre (un générateur de nombres aléatoires), mais en échange, vous obtenez une définition et un comportement (généralement) nettement meilleurs.

std::random_shuffle Était assez mal défini. Il utilisait généralement Rand() pour générer les nombres aléatoires, mais rien ne disait si (et si oui comment) il appelait srand, donc vous ne pouviez pas dépendre (par exemple) de Rand étant semé comme vous le vouliez (et si vous le semiez, vous ne pouviez pas dépendre de ce qu'il soit utilisé). Si la mémoire est bonne, il y avait aussi un langage déroutant (et quelque peu contradictoire) qui pourrait être interprété comme disant que random_shuffle Ne pouvait pas du tout utiliser Rand, et/ou qu'il ne pouvait pas ' t semez-le avec srand. Même au mieux, de nombreuses implémentations de Rand() étaient assez médiocres, donc même au mieux, vous ne pouviez pas dépendre de résultats utiles.

Conclusion: random_shuffle N'est pas une perte. Utilisez std::shuffle À la place, et votre code sera bien meilleur pour cela.

43
Jerry Coffin

Nous pouvons trouver la justification dans ce document N3775: Deprecating Rand and Friends qui dit:

Nous proposons donc maintenant d'exécuter la prochaine étape de ce plan pour décourager l'utilisation de la fonction C traditionnelle Rand ainsi que sa fonction d'amorçage associée srand et la macro limite supérieure Rand_MAX.6 En particulier, nous proposons de commencer cette transition en dépréciant formellement:

  • Rand, srand et Rand_MAX et
  • algorithme random_shuffle () (en gardant shuffle, cependant).

La justification de la dépréciation de random_shuffle () est qu'une surcharge est spécifiée de manière à dépendre de Rand, tandis que l'autre surcharge est spécifiée de manière à exiger un objet de distribution difficile à produire de la part de l'utilisateur; une telle distribution est déjà une partie implicite du shuffle, que nous conservons.

et le document ultérieur Discouraging Rand () en C++ 14, v2 qui réitère cette position.

Mettre à jour

Comme Howard Hinnant le note, N3775 A une erreur: Rand_shuffle() est autorisé mais non requis pour utiliser Rand() sous le capot mais cela ne changera pas la raison.

16
Shafik Yaghmour

random_shuffle Est déconseillé parce que son RNG n'est pas spécifié - pas seulement que vous ne devez pas le spécifier, mais que la norme elle-même ne le spécifie pas. Sur VC++, par exemple, il utilise Rand(), qui est vraiment mal implémenté!

6
Cory Nelson