9

STL は、デフォルトのコンパレータとして「より小さい」を使用します。reference_wrapper<> でラップされたオブジェクトの STL コンパレーター呼び出しは、基になるクラスに "<" 演算子が定義されていてもコンパイルされません。

これは、メンバー関数の場合、LHS.operator<(RHS)のLHSで暗黙的な変換が行われないためです。コンパレータとして無料版を使用することを確認しました。

ただし、reference_wrapper が "<" 演算子を提供し、基になる "<" を呼び出す場合、free 関数を使用する必要はなくなります。

reference_wrapper (VS11 Beta xrefwrap.h から取得) のコードに次の追加を行い、"<" 演算子が定義されている私のバージョンの reference_wrapper<> でラップされたクラスで std::map を使用できました。

    bool operator <(reference_wrapper<_Ty> const rhs) const {
    return this->get() < rhs.get();
}

後で追加: 私の理解が正しければ、 reference_wrapper<> は、ptr 関連の構文を隠しながら、多くのライブラリで必要とされる ptr に関連付けられた copy/assign セマンティクスを提供します。これにより、ローカル コピーのオーバーヘッドなしで、参照型の構文を使用できます。ptrを使用した例と比較すると、reference_wrappers のポイントの1 つが完全に失われています。つまり、ptr 型の構文の使用を避けたいということです。

現状では、オブジェクトを直接処理するコードは、オブジェクトが reference_wrappers でラップされると機能しなくなります。言うまでもなく、「<」はデフォルトのコンパレータであり、実際に特別なものになっています。既存のコードのかなりの割合で、オブジェクトはこれらを定義して、特別なコンパレーターの必要性を取り除きます。

後で追加 #2: この機能の歴史は、ptr 構文の使用を避けることが本来の意図ではなかったことを示唆しています。ただし、これが初めてboostに導入されてから10年が経ちました。多数の新しいプログラマーがptr ベースの構文(間違いなく ptr フリー言語の影響を受けている) を避けるように「ガイド」されているため、特に STL コンテナーにオブジェクトを格納するレガシー コードを処理する場合に、この機能がよりシームレスに機能する場合、この機能はますます有用になる可能性があります。値は全体にコピーされます。

後で追加 #3: 最小限のコード変更でレガシー コードを改善する 時間の経過とともにシン クラスが重くなり、コンテナー内のオブジェクトのサイズが大きくなります。パフォーマンスを向上させる簡単な方法は、ラップされたオブジェクトを介してコピーを回避することです。これにより、コードへの最小限の変更で余分なコピーなしで「C ptr」タイプのパフォーマンスが提供されます。

std::map<const Object, string> objTable;
// can be rewritten as to avoid object copies using the
// __myOwn::reference_wrapper which contains the '<' operator
std::map<__myOwn::reference_wrapper<const Object>, string> rwTable_myOwn;

// which works with out any non-member free comparator functions
rwTable_myOwn[a]="One"; // Compiles and works

// When using the table with the std::reference_wrapper
std::map<std::reference_wrapper<const Object>, string> rwTable_std;
//the map does not work
rwTable_std[a]="One"; // Fails to compile it needs the custom non-member comparator
4

1 に答える 1

9

いいえ、すべきではありません。参照reference_wrapperを値としてラップする以外に何もするのは仕事ではありません。

2つのを比較する必要がある場合reference_wrapper<T>(これはへの参照ではありませんT)、それを機能させるのはあなたの仕事です。同じ理由std::set<T*>で、デフォルトで比較をとして定義することはありませんstd::less<T>(*x, *y)。あなたの場合もそうすべきではありません。ラッパーは単なるnull以外のポインターです。

なぜ単一の比較演算子またはすべての比較演算子で停止するのですか?すべての標準関数の参照ラッパーをオーバーロードしてみませんか?解決策がとても簡単な場合、それは価値がないからです。

于 2012-05-24T02:34:48.780 に答える