web-dev-qa-db-ja.com

C ++ 17ラムダキャプチャ* this

C++ 17は、このオブジェクトのcopy captureを値ごとに追加します [*this]のキャプチャ指定

これはどのように役立ちますか? thisをキャプチャするのとどう違うのですか?これは、C++ 14で[tmp = *this]を使用してすでに達成できませんか?


P0018R が例で[=, tmp = *this]ではなく[tmp = *this]を使用する理由を説明するボーナス。彼らが[tmp = *this]を使用した場合、リストされているC++ 14ソリューションの欠点はすべて排除されます。

27
bolov

それはどのように役立ちますか?これは、*thisのコピーが必要な場合に便利です。たとえば、*this自体がラムダが評価されるまでに無効になる場合などです。

thisのキャプチャとどう違うのですか?オブジェクトのcopyを作成するので、ラムダが評価されると、そのthisポインターは元のオブジェクトではなくコピーを参照します。

C++ 14で[tmp = *this]を使用して実現できますか?可能ですが、メンバーアクセスの前に[*this]を付けずにコードを移動できるため、tmp.の方が便利です。それ以外の場合、特に[=, tmp = *this]を使用すると、コピーを参照するつもりだったときに、特に元のオブジェクトのメンバーを誤って参照する可能性があります(特に、カットアンドペーストプログラミングの習慣がある場合)。この場合、[=,*this]は安全な代替手段です。元のオブジェクトはラムダの本体内からアクセスできません(少なくともthisポインタを介してはアクセスできません)。

29
Toby Speight

*thisshared_ptrを共有状態に維持するハンドルクラスであると想像してください。

共有される実装は、(たとえば)プロトコルハンドラーのステートマシンです。

ハンドルクラスは一連の非同期ハンドラーを介して渡されるため、それ自体をコピー可能にする必要があります。各ハンドラーは共有状態を変更します。

これの強力な使用例は、カスタムasioサービス(たとえば、http_protocol_socket)で使用するプロトコルハンドラーです。

[=, tmp = *this]は、thisポインター自体を含め、かなり危険なことに、*thistmpに具体的にキャプチャするだけでなく、すべての変数を値によって無差別にキャプチャします。

この使用例では、宙ぶらりんのポインターである可能性が高いため、非同期ハンドラーでthisを誤って参照することは危険です。これは、発生するのを待っているバグです。

[tmp=*this]*thisのみをキャプチャします。

4
Richard Hodges