¿Por qué los métodos std:: shuffle están en desuso en C++14?


Según el cppreference.com sitio de referencia en std:: shufle , el siguiente método está siendo obsoleto en c++14:

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

¿Por qué ya no podremos llamar a la siguiente función sin pasar un tercer parámetro?

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

No parece que una desaceleración de función diferente tenga un parámetro predeterminado. ¿Cuál es la razón detrás de esto? ¿Se añadió algún tipo de alternativa?

Author: Trevor Hickey, 2014-03-24

4 answers

std::random_shuffle puede hacer uso, bajo el capó, de random C familia de funciones. Estas funciones usan estado global para semillas y otro estado.

Así que está en desuso porque shuffle hará lo mismo, pero mejor. Es decir, utiliza el nuevo encabezado <random> de C++11 que no usa estado global, sino sus propios objetos haciendo uso de generadores, dispositivos y distribuciones.

 44
Author: Germán Diago,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-03 23:52:35

std::random_shuffle se sustituye (efectivamente) por std::shuffle. Necesita pasar un tercer parámetro (un generador de números aleatorios), pero a cambio de eso obtiene una definición y un comportamiento (típicamente) sustancialmente mejores.

std::random_shuffle estaba bastante mal definido. Se utiliza normalmente rand() para generar los números aleatorios, pero nada dijo de si (y cómo) se llama srand, por lo que no podía depender (por ejemplo) en rand siendo sembradas cómo querías (y si cabeza de serie, no lo podía depender de que ser puesto en uso). Si la memoria no me falla, también hubo un lenguaje confuso (y algo contradictorio) que podría interpretarse como diciendo que random_shuffle no podía usar rand en absoluto, y/o que no podía sembrarlo con srand. Incluso en el mejor de los casos, muchas implementaciones de rand() eran bastante pobres, por lo que incluso en el mejor de los casos no podía depender de resultados útiles.

En pocas palabras: random_shuffle no hay pérdida. Use std::shuffle en su lugar, y su código será mucho mejor para ello.

 41
Author: Jerry Coffin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-24 02:35:38

Podemos encontrar la justificación en este documento N3775: Desaprobación de rand y Amigos {[5] } que dice:

Por lo tanto, ahora proponemos ejecutar el siguiente paso de este plan para desalentar el uso de la función C tradicional rand, así como su función de siembra asociada srand y macro de límite superior RAND_MAX.6 En particular, proponemos comenzar esta transición formalmente desaprobando:

  • rand, srand, y RAND_MAX y{[14]]}
  • algoritmo random_shuffle () (manteniendo shuffle, sin embargo).

La razón para desaprobar random_shuffle() es que se especifica una sobrecarga para depender en rand, mientras que la otra sobrecarga se especifica para requerir una distribución difícil de producir objeto del usuario; tal distribución ya es una parte implícita de shuffle, que retenemos.

Y el documento posterior Desalentando a rand () en C++14, v2 que reitera esto posición.

Actualización

Como señala Howard Hinnant N3775 tiene un error: rand_shuffle() se permite pero no se requiere usar rand() bajo el capó, pero eso no cambiaría la razón de ser.

 15
Author: Shafik Yaghmour,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-14 05:35:10

random_shuffle está en desuso porque su RNG no está especificado {no solo que no tiene que especificarlo, sino que el estándar en sí no lo especifica. En VC++, por ejemplo, utiliza rand(), que se implementa muy mal!

 6
Author: Cory Nelson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-24 02:35:17