[英]Lambda (passing a lambda to a function by reference vs by value)
When std::function is created with a lambda, the std::function internally makes a copy of the lambda object. 因此,我們對 fn() 的調用實際上是在 lambda 的副本上執行的,而不是實際的 lambda。
According to the statements above, what is the point of passing a lambda by 'reference using &' or passing by 'value' in the code below while the std::function always makes a copy of the lambda object?
換句話說,在下面的代碼中,當'invoke' function 的參數通過引用或值傳遞時,lambda 的哪一部分將不會被修改/生效?
#include <iostream>
#include <functional>
void invoke(const std::function<void(void)>& fn) // # PASS LAMBDA BY REFERENCE*********************
{
fn();
}
int main()
{
int i{ 0 };
// Increments and prints its local copy of @i.
auto count{ [i]() mutable {
std::cout << ++i << '\n';
} };
invoke(count);
invoke(count);
invoke(count);
return 0;
}
#include <iostream>
#include <functional>
void invoke(const std::function<void(void)> fn) // # PASS LAMBDA BY VALUE*********************
{
fn();
}
int main()
{
int i{ 0 };
// Increments and prints its local copy of @i.
auto count{ [i]() mutable {
std::cout << ++i << '\n';
} };
invoke(count);
invoke(count);
invoke(count);
return 0;
您正在混合兩件事-通過引用傳遞和強制轉換。
這大致是 lambda 的實現方式:
struct Lambda{
//Capture by value
Lambda(int i):_i(i){}
void operator()() const{
std::cout << ++_i << '\n';
}
mutable int _i;
};
//BTW const is somewhat redundant
void invoke1(const Lambda fn) // # PASS LAMBDA BY VALUE
{
fn();
}
//Const is important, but not yet.
void invoke2(const Lambda& fn) // # PASS LAMBDA BY REFERENCE
{
fn();
}
int main()
{
int i{ 0 };
// Increments and prints its local copy of @i.
Lambda count{i};
invoke1(count);//1
invoke1(count);//1
invoke1(count);//1
invoke2(count);//1
invoke2(count);//2
invoke2(count);//3
return 0;
}
該代碼生成您可能想要的 output。 請注意, mutable
用法是完全不正確的,但我是這樣做的,因此代碼可以編譯。 有關std::function
如何做到這一點,請參閱鏈接。
正如@Jarod42 所寫, lambda 不是std::function
,但它可以通過std::function
的構造函數隱式轉換為一個。 這根本不是std::function
的實現方式,為了允許捕獲任何可調用對象,涉及到更多的魔法。 但它說明了這一點。
#include <iostream>
#include <functional>
struct Lambda{
//Capture by value
Lambda(int i):_i(i){}
void operator()() const{
std::cout << ++_i << '\n';
}
mutable int _i;
};
struct Function{
//Makes a copy.
Function(Lambda lambda):_lambda(std::move(lambda)){}
void operator()() const{
_lambda();
}
Lambda _lambda;
};
void invoke1(const Function fn) // # PASS FUNCTION BY VALUE
{
fn();
}
//Const is very important.
void invoke2(const Function& fn) // # PASS FUNCTION BY REFERENCE
{
fn();
}
int main()
{
int i{ 0 };
// Increments and prints its local copy of @i.
Lambda count{i};
invoke1(count);//1
invoke1(count);//1
invoke1(count);//1
invoke2(count);//1
invoke2(count);//1
invoke2(count);//1
return 0;
}
B 所有invoke2
調用仍會打印1
,因為在每次調用時都會創建一個新的Function
object,它會創建自己的count
lambda666965 的本地副本。 當然,對於invoke1
調用也發生了同樣的情況,但這沒有區別,因為無論哪種方式都可以進行復制。
請注意, invoke2(const Function&)
中的 const 非常重要,沒有它,調用將導致編譯錯誤。 這是因為const Function&
允許參數綁定到 L-values 和 R-values(~temporaries)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.