web-dev-qa-db-ja.com

std :: shuffleメソッドがC ++ 14で廃止されたのはなぜですか?

cppreference.comstd :: shufle のリファレンスサイトによると、次のメソッドはc ++ 14で廃止されています:

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

3番目のパラメーターを渡さないと、次の関数を呼び出せなくなるのはなぜですか?

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

別の関数の減速にデフォルトのパラメーターセットがあるようには見えません。この背後にある理由は何ですか?ある種の代替が追加されましたか?

51
Trevor Hickey

std::random_shufflemay内部でrandom Cファミリーの関数を使用します。これらの関数は、シードおよびその他の状態にグローバル状態を使用します。

shuffleも同じように動作するため、廃止予定ですが、より優れています。つまり、新しい<random>グローバル状態を使用しないC++ 11からのヘッダーですが、ジェネレーター、デバイス、およびディストリビューションを使用する独自のオブジェクトです。

46
Germán Diago

_std::random_shuffle_は(事実上)_std::shuffle_に置き換えられます。 3番目のパラメーター(乱数ジェネレーター)を渡す必要はありますが、それと引き換えに、実質的に優れた定義と(通常は)動作が得られます。

_std::random_shuffle_の定義はかなり不十分です。通常はRand()を使用して乱数を生成しましたが、それがsrandを呼び出すかどうか(およびその場合はその方法)については何も言われていないため、Rand必要な方法でシードされている(そして、シードされている場合、それが使用されることに依存することはできませんでした)。メモリが機能する場合、_random_shuffle_はRandをまったく使用できない、および/または使用できないと解釈される可能性のある混乱する(そして多少自己矛盾する)言語もありましたsrandをシードします。せいぜいRand()の多くの実装はかなり貧弱でした。そのため、せいぜい有用な結果に頼ることさえできませんでした。

結論:_random_shuffle_は失われません。代わりに_std::shuffle_を使用してください。そうすれば、コードがはるかに良くなります。

43
Jerry Coffin

このドキュメントで根拠を見つけることができます N3775:Rand and Friendsの非推奨 は次のように述べています。

したがって、この計画の次のステップを実行して、従来のC関数Randとそれに関連するシード関数srandおよび上限マクロRand_MAXの使用を阻止することを提案します。6 特に、この移行を正式に廃止することから始めることを提案します。

  • Rand、srand、およびRand_MAXおよび
  • アルゴリズムrandom_shuffle()(ただし、シャッフルを維持)。

Random_shuffle()を廃止する理由は、Randに依存するように1つのオーバーロードが指定されているのに対し、他のオーバーロードは、ユーザーが生成するのが難しい配布オブジェクトを必要とするように指定されていることです。そのような分布はすでにシャッフルの暗黙の一部であり、私たちはそれを保持しています。

そして後のドキュメント C++ 14のRisco(Discouraging)(v2 この位置を繰り返します。

更新

ハワード・ヒナント氏が指摘しているように、N3775にはエラーがあります。Rand_shuffle()は許可されていますが、内部でRand()を使用する必要はありませんが、根拠は変わりません。

16
Shafik Yaghmour

_random_shuffle_は、RNGが指定されていないため廃止されています-それだけではなくyoで指定する必要はありませんが、標準自体では指定されていません。たとえば、VC++ではRand()を使用していますが、これは実装が不十分です!

6
Cory Nelson