簡體   English   中英

Lambda(通過引用與按值將 lambda 傳遞給 function)

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM