Подтвердить что ты не робот

Почему методы 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

Не похоже, что разное торможение функции имеет набор параметров по умолчанию. В чем причина этого? Была ли добавлена ​​альтернатива?

4b9b3361

Ответ 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(), который выполняется очень плохо!