簡體   English   中英

C++ lambda 捕獲 this 與通過引用捕獲

[英]C++ lambda capture this vs capture by reference

如果我需要生成一個調用成員函數的 lambda,我應該通過引用捕獲還是捕獲“this”? 我的理解是 '&' 僅捕獲使用的變量,但 'this' 捕獲所有成員變量。 所以最好使用'&'?

class MyClass {
  public:
    int mFunc() {
      // accesses member variables
    }

    std::function<int()> get() {
      //return [this] () { return this->mFunc(); };
      //  or
      //return [&] () { return this->mFunc(); };
    }

  private:
    // member variables
}

對於您提供的特定示例,通過this捕獲正是您想要的。 從概念上講,通過引用捕獲this並沒有多大意義,因為您無法更改this的值,您只能將其用作訪問類成員或獲取類實例地址的指針. 在您的 lambda 函數中,如果您訪問隱式使用this指針的內容(例如,您調用成員函數或訪問成員變量而不顯式使用this ),編譯器會將其視為您已經使用了this 您也可以列出多個捕獲,因此如果您想捕獲成員和局部變量,您可以獨立選擇是按引用還是按值捕獲它們。 以下文章應該為您提供 lambdas 和捕獲的良好基礎:

https://crascit.com/2015/03/01/lambdas-for-lunch/

此外,您的示例使用std::function作為將 lambda 傳遞回調用者的返回類型。 請注意, std::function並不總是像您想象的那么便宜,因此如果您能夠直接使用 lambda 而不是必須將其包裝在std::function ,那么它可能會更有效。 以下文章雖然與您的原始問題沒有直接關系,但仍可能為您提供一些與 lambdas 和std::function相關的有用材料(請參閱“存儲函數對象的替代方法”部分,但一般而言,這篇文章可能會引起您的興趣):

https://crascit.com/2015/06/03/on-leaving-scope-part-2/

這里很好地解釋了&this和其他在捕獲列表中使用時指示的內容。

在您的情況下,假設您所要做的就是調用當前正在執行的方法的this實際引用的實例的成員函數,將this放入捕獲列表中就足夠了。

捕獲this和通過引用捕獲是兩個正交的概念。 您可以使用一個、兩個或一個都不使用。 通過引用捕獲this沒有意義,但您可以通過引用捕獲其他變量,同時按值捕獲this

這不是一個明確的情況,其中一個比另一個好。 相反,兩者(至少可能)完成的事情略有不同。 例如,考慮這樣的代碼:

#include <iostream>

    class foo { 
        int bar = 0;
    public:
        void baz() {
            int bar = 1;
            auto thing1 = [&] { bar = 2; };
            auto thing2 = [this] { this->bar = 3; };

            std::cout << "Before thing1: local bar: " << bar << ", this->bar: " << this->bar << "\n";    
            thing1();
            std::cout << "After thing1: local bar: " << bar << ", this->bar: " << this->bar << "\n";
            thing2();
            std::cout << "After thing2: local bar: " << bar << ", this->bar: " << this->bar << "\n";
        }
    };


int main() { 
    foo f;
    f.baz();
}

如您所見,捕獲this捕獲可以通過this引用的變量。 在這種情況下,我們有一個隱藏實例變量的局部變量(是的,這通常是一個壞主意,但在這種情況下,我們使用它來顯示每個人的部分功能)。 正如我們在運行程序時看到的那樣,通過引用捕獲this與隱式捕獲得到不同的結果:

Before thing1: local bar: 1, this->bar: 0
After thing1: local bar: 2, this->bar: 0
After thing2: local bar: 2, this->bar: 3

至於捕獲所有內容與僅捕獲您使用的內容的細節:兩者都不會捕獲您不使用的任何變量。 但是,由於this是一個指針,捕獲該變量可以讓您訪問它指向的所有內容。 這是不是唯一的this雖然。 捕獲任何指針將使您可以訪問它指向的任何內容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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