ラムダがC ++でどのように機能するかを深く理解しようとしています。私は次のコードを書きました。
#include <iostream>
#include <functional>
struct A
{
A() { std::cout << "A" << (data = ++count) << ' '; }
A(const A& a) { std::cout << "cA" << (data = a.data + 20) << ' '; }
A(A&& a) { std::cout << "mA" << (data = std::move(a.data) + 10) << ' '; }
~A() { std::cout << "dA" << data << ' '; }
int data;
static int count;
};
int A::count = 0;
void f(A& a, std::function<void(A)> f)
{
std::cout << "( ";
f(a);
std::cout << ") ";
}
int main()
{
A temp, x;
auto fun = [=](A a) {std::cout << a.data << '|' << x.data << ' ';};
std::cout << "| ";
f(temp, fun);
std::cout << "| ";
}
出力は以下のとおりです。
A1 A2 cA22 | cA42 mA52 dA42(cA21 mA31 31 | 52 dA31 dA21)dA52 | dA22 dA2 dA1
'mA52'のmoveコンストラクター呼び出しを除いて、これは私には非常に明白です。値による変数キャプチャを使用していることに注意してください。したがって、moveコンストラクターがないと、copyコンストラクターがここで呼び出されます。このステップで追加のコピー/移動があるのはなぜですか?fun
引数として値が渡された場合、オブジェクトは1回だけコピーされると予想されますf
。さらに、オブジェクトの最初のコピーはすぐに破棄されます。どうして?この中間コピーは何ですか?
ラムダ型と呼びましょうL
。名前はありませんが、名前なしで参照すると混乱します。
コンストラクターstd::function<void(A)>(L l)
はL
値を取ります。これには、元ののコピーの作成が含まれfun
ます。
次に、コンストラクターはラムダをラッパーl
によって管理されるストレージに移動しstd::function<void(A)>
ます。その移動には、キャプチャされたエンティティの移動も含まれます。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加