3

各Wバイト幅のNレコードの連続バッファがあります。NとWはどちらもコンパイル時に不明です。N*Mは500mbの注文です。これをsort()やnth_element()などの標準のSTL引数で使用したいと思います。手元にコンパレータがあります。すでに実装されている方法はありますか?

これまでのところ、私は2つの方法を考えました。

1)インデックス0 ... Nで満たされた追加のベクトルを使用し、データの代わりに(カスタムコンパレータを使用して)並べ替えて、並べ替えられた順序でデータレコードに似せるようにし、そのベクトルに従ってデータレコードを移動します。欠点:追加のメモリ、データレコードの順序を修正するための追加の難しさ、これはわずかに重要です。

2)レコードに似た一時的な「仮想」クラスインスタンスを返すカスタムイテレータ(Wを認識)を作成し、そのクラスのswap()をオーバーロードして、メモリのチャンクを交換します。欠点:ややトリッキーで、やや壊れやすい(swap()が使用されることを知っているなど、いくつかのSTL内部に従う必要があります)。

4

3 に答える 3

4

2 番目のオプションであるカスタム イテレータの作成は、実行可能なアプローチであり、非常にうまく機能します。

使用されることに依存する必要はありませんswap。反復子が逆参照されたときに返すプロキシ オブジェクトの代入演算子をオーバーロードするだけで済みます。

(C++11 では、要素を「交換」するアルゴリズムと関数は、swapADL 経由で見つかった関数を使用する必要があることに注意してください。ただし、特にバイト配列を移動するだけの場合は、代入演算子をオーバーロードすることをお勧めします。)

頭のてっぺんからの一般的な実装については知りませんが、出発点として、stride_iterator私のライブラリの 1 つ (ファイルの下部近く) から調べることができます。バイト配列をラップし、算術演算子をオーバーライドして、イテレータを一度に N バイトずつ移動します。ここで、N は実行時にのみ認識されます。

于 2012-08-07T16:23:43.250 に答える
2

私は 2 番目のアプローチを選択しますが、カスタム コピーではなく、カスタム コピー セマンティクスを提供しますswap。反復子の値の型を、void*メンバーを保持するクラスにし、そのメンバーが指すレコードをコピーするコピー コンストラクターと代入演算子を使用します。これは、実装の詳細には依存しません。

于 2012-08-07T16:23:27.990 に答える
1

swap()私はオプション 2) に投票しますが、実際にはスタブ クラスをオーバーロードする必要はありません。あなたはただする必要があります:

  • イテレータによって返される「スタブ」クラスを作成します
  • 幅 W のメモリのチャンクを割り当てるデフォルト ctor を実装する
  • 幅 W のメモリのチャンクを割り当て、入力されたメモリのチャンクをコピーするコピー ctor を実装します。
  • メモリのチャンクが 1 つのインスタンスから別のインスタンスにコピーされるように、代入演算子をオーバーロードします。

このようにswap()して、クラスで自動的に機能します。

于 2012-08-07T16:24:17.820 に答える