問題タブ [reference-wrapper]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - `std::reference_wrapper`s でテンプレート インスタンスを推定できないのはなぜですか?
タイプ のオブジェクトがありT
、それを参照ラッパーに入れたいとします。
if (p < q)
参照ラッパーにはラップされた型への変換があるため、これで簡単に言うことができます。すべてが順調で、参照ラッパーのコレクションを元のオブジェクトと同じように処理できます。
(以下にリンクされている質問が示すように、これは既存のコレクションの代替ビューを生成する便利な方法であり、元のコレクションとの更新の整合性を維持するだけでなく、完全なコピーのコストを負担することなく自由に再配置できます。 )
ただし、一部のクラスではこれが機能しません。
私の回避策は、この回答のように述語を定義することです *; しかし、私の質問は次のとおりです。
演算子を参照ラッパーに適用し、ラップされた型の演算子を透過的に使用できるのはなぜですか? なぜ失敗するのstd::string
ですか?std::string
テンプレートインスタンスであるという事実と何の関係があるのでしょうか?
*)更新:回答に照らして、使用std::less<T>()
は一般的な解決策のようです。
c++ - std::reference_wrapper にデフォルトのコンパレータ "<" 演算子を含める必要がありますか?
STL は、デフォルトのコンパレータとして「より小さい」を使用します。reference_wrapper<> でラップされたオブジェクトの STL コンパレーター呼び出しは、基になるクラスに "<" 演算子が定義されていてもコンパイルされません。
これは、メンバー関数の場合、LHS.operator<(RHS)のLHSで暗黙的な変換が行われないためです。コンパレータとして無料版を使用することを確認しました。
ただし、reference_wrapper が "<" 演算子を提供し、基になる "<" を呼び出す場合、free 関数を使用する必要はなくなります。
reference_wrapper (VS11 Beta xrefwrap.h から取得) のコードに次の追加を行い、"<" 演算子が定義されている私のバージョンの reference_wrapper<> でラップされたクラスで std::map を使用できました。
後で追加: 私の理解が正しければ、 reference_wrapper<> は、ptr 関連の構文を隠しながら、多くのライブラリで必要とされる ptr に関連付けられた copy/assign セマンティクスを提供します。これにより、ローカル コピーのオーバーヘッドなしで、参照型の構文を使用できます。ptrを使用した例と比較すると、reference_wrappers のポイントの1 つが完全に失われています。つまり、ptr 型の構文の使用を避けたいということです。
現状では、オブジェクトを直接処理するコードは、オブジェクトが reference_wrappers でラップされると機能しなくなります。言うまでもなく、「<」はデフォルトのコンパレータであり、実際に特別なものになっています。既存のコードのかなりの割合で、オブジェクトはこれらを定義して、特別なコンパレーターの必要性を取り除きます。
後で追加 #2: この機能の歴史は、ptr 構文の使用を避けることが本来の意図ではなかったことを示唆しています。ただし、これが初めてboostに導入されてから10年が経ちました。多数の新しいプログラマーがptr ベースの構文(間違いなく ptr フリー言語の影響を受けている) を避けるように「ガイド」されているため、特に STL コンテナーにオブジェクトを格納するレガシー コードを処理する場合に、この機能がよりシームレスに機能する場合、この機能はますます有用になる可能性があります。値は全体にコピーされます。
後で追加 #3: 最小限のコード変更でレガシー コードを改善する 時間の経過とともにシン クラスが重くなり、コンテナー内のオブジェクトのサイズが大きくなります。パフォーマンスを向上させる簡単な方法は、ラップされたオブジェクトを介してコピーを回避することです。これにより、コードへの最小限の変更で余分なコピーなしで「C ptr」タイプのパフォーマンスが提供されます。
c++ - std::reference_wrapperと並列のstd::value_wrapperのようなものはありますか?
(更新:const Foo
この質問は、との異なる意味を持つオブジェクトの値によって渡されるラッパークラスの実装に由来します。これは、ここの人々からの強い意見に完全にFoo
基づいた動きです。やって来たので、それをとに交換しました。 機械的な置換が意味をなさないことは明らかです。そして、などのより複雑なものが必要になります...それを正しく書く方法はわかりませんが誤解をお詫びしますが、実際には多くの質問よりも明らかになると思うので、ここに残しておきます。)const Foo*
Foo*
Wrapper<Foo>
const Wrapper<Foo>
Wrapper<Foo>
Wrapper<const Foo>
この質問を調べてみると、これはできないという考えと平行しているように見えました。
参照と同様に、const値を再ターゲットすることはできません。次のことを行うとコンパイルされますが、私が(この種のシナリオで)意図していることではありません。
(私の理解から)reference_wrapper
次のようなもので、リファレンスケースでこれを回避できるようです:
value_wrapper
似たようなことをする""がそこにあるのだろうか。const-correctnessの理由でconstである値でアイテムを保持する変数が必要なのは、私には合理的だと思います...変更しないからではありません。 (たとえば、前のノードを関数に渡すことが新しいノードを取得する方法である、そのツリー内のノードへのconstアクセスしか持たないにもかかわらず、プレオーダーツリーウォークで現在のノードを追跡するなど)
不格好になりたい場合は、 :を使用std::pair<const Foo, bool>
して無視することができます。bool
しかし、私自身のバージョンの ""を実装する以外に、これに対処するためのより良い方法はありvalue_wrapper
ますか?
c++ - C++ std::reference_wrapper はどのように暗黙的に参照に変換されますか?
最近、std::reference_wrapper
クラスを使い始めました。get()
プリミティブ参照の特定の使用法を置き換えるときに、関数を使用して、通常の参照を取る関数にパラメーターとして reference_wrappers を渡す必要がないことに気付きました。
std::reference_wrapper
関数に渡されたときに、どのようにプリミティブ参照に暗黙的に変換されますか?
c++ - std :: reference_wrapperはいつT&に変換されますか?
次のコードを検討してください。
このコードは「8」を出力します。fun()のtは自動的にint&に変換されると思います。
しかし、に置き換えるt+=8
とt=8
、プログラムはコンパイルされません。
なんで?
c++ - ベクトルc++ 11の参照ラッパー要素へのアクセス
グラフ クラス:
グラフを使用する別のクラスでは:
今、優先キュー ( PECMP someQueue
) の最初の要素にアクセスしようとしています。
ただし、次のエラーが表示されます。
参照ラッパーに格納された要素にアクセスするより良い方法は何ですか? ありがとう
c++ - ベクトルを渡す> ベクトル化?
大きな がありますstd::vector<int> a
が、そのサブセットのみで作業したいと考えています。アイデアはstd::vector<reference_wrapper<int> > refa
、上記のサブセットのみを含む を作成することでした (mwe では、すべての要素 1< a
< 4)。次に、またはを引数としてrefa
期待する関数に渡したいと思います (これらを とともに使用したいため)。かなり大きくなる可能性があるため、選択を複数回行うことは避けたいと思います。std::vector<int>
std::vector<int>&
a
a
質問
refa
関数に適切に渡すにはどうすればよいですか? 私が欲しいのはbar(refa)
、foobar(refa)
働くことです。
関数を (あまり) 変更せずに、問題を解決するより良い方法はありますか?
コード
注記
int
は、例を単純にするためにここでのみ使用されています。