Почему методы std:: shuffle устарели в С++ 14?
В соответствии с cppreference.com ссылкой на std:: shufle, следующий метод устарел в С++ 14:
template< class RandomIt >
void random_shuffle( RandomIt first, RandomIt last );
Почему нам не удастся вызвать следующую функцию без передачи третьего параметра?
std::random_shuffle(v.begin(),v.end()); //no longer valid in c++14
Не похоже, что разное торможение функции имеет набор параметров по умолчанию. В чем причина этого? Была ли добавлена альтернатива?
Ответы
Ответ 1
std::random_shuffle
может использовать под капотом семейство функций random
C. Эти функции используют глобальное состояние для семян и другого состояния.
Поэтому он устарел, потому что shuffle
будет делать то же самое, но лучше. А именно, он использует новый заголовок <random>
из С++ 11, который не использует глобальное состояние, но его собственные объекты используют генераторы, устройства и дистрибутивы.
Ответ 2
std::random_shuffle
(эффективно) заменяется на std::shuffle
. Вам нужно передать третий параметр (генератор случайных чисел), но взамен этого вы получите существенно лучшее определение и (как правило) поведение.
std::random_shuffle
был довольно плохо определен. Обычно он использовал rand()
для генерации случайных чисел, но ничто не говорило, было ли (и если да, как) оно называлось srand
, поэтому вы не могли зависеть (для одного примера) в rand
от посева, как вы хотели (и если вы высевали его, вы не могли бы зависеть от того, что его использовали). Если память служит, был также некоторый сбивающий с толку (и несколько противоречивый) язык, который можно было бы интерпретировать как говорящий, что random_shuffle
вообще не может использовать rand
и/или что он не может засеять его с помощью srand
. Даже в лучшем случае многие реализации rand()
были довольно плохими, поэтому даже в лучшем случае вы не могли зависеть от полезных результатов.
Нижняя строка: random_shuffle
не является потерей. Вместо этого используйте std::shuffle
, и ваш код будет намного лучше для него.
Ответ 3
Мы можем найти логическое обоснование в этом документе N3775: Устаревание rand и друзей, в котором говорится:
Поэтому мы теперь предлагаем выполнить следующий шаг этого плана, чтобы препятствовать использованию традиционная функция C rand, а также связанная с ней функция посева srand и макрос верхнего предела RAND_MAX. 6 В частности, мы предлагаем начать этот переход формальным образом:
- rand, srand и RAND_MAX и
- algorithm random_shuffle() (сохраняя, однако, тасовку).
Обоснование неустранимого random_shuffle() заключается в том, что одна перегрузка задана так, чтобы она зависела на rand, в то время как другая перегрузка указана так, чтобы требовать жесткого распределения объект от пользователя; такое распределение уже является неявной частью тасования, которую мы сохраняем.
и более поздний документ Отказ от rand() в С++ 14, v2, который повторяет эту позицию.
Обновить
Как отмечает Ховард Хиннант, N3775
имеет ошибку: rand_shuffle()
разрешен, но не требуется использовать rand()
под капотом, но это не изменит логики.
Ответ 4
random_shuffle
устарел, потому что его RNG не указан, а не только его не нужно указывать, но сам стандарт не указывает его. Например, в VС++ он использует rand()
, который выполняется очень плохо!