[英]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
相關的有用材料(請參閱“存儲函數對象的替代方法”部分,但一般而言,這篇文章可能會引起您的興趣):
這里很好地解釋了&
、 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.