[英]Accessing lambda capture initialized variable outside the lambda in C++
在 C++14/17 中,如何訪問 lambda 范圍之外的 lambda 捕獲初始化變量?
來源:
#include <iostream>
using namespace std;
int main(){
auto test = [value1 =0]() mutable {value1+=1; return value1;};
cout << test() << endl;
cout << test() << endl;
//cout << value1 << endl;//error: ‘value1’ was not declared in this scope
}
輸出:
1
2
value1
變量是否可以在test()
lambda 的范圍之外訪問? lambda 捕獲初始化變量的生命周期是多少?
嘗試在 lambda 之外訪問value1
會出現以下error: 'value1' was not declared in this scope
。
使用 gcc 版本 7.3.0 (Ubuntu 7.3.0-21ubuntu1~14.04) 編譯。
lambda 只是內聯定義的結構和該結構上的operator()
重載(以及用於創建該結構類型的對象operator()
的緊湊定義。 Lambda“捕獲”只是這個結構的成員變量,由類型的構造函數初始化。 這是 C++ lambda 必須具有按值與按引用捕獲的語法的原因之一。
但是結構的成員變量是私有的。 並且由於編譯器生成的結構主要是實現定義的,因此標准不需要公開具有這些名稱的成員。 如果需要,編譯器生成的結構可以使用其他名稱; 編譯器只需要重新映射這些名稱的 in-lambda 用法即可引用成員的名稱。
所以不,任何形式的lambda 捕獲都不能被該 lambda 之外的世界訪問。 如果您捕獲對對象的引用,那么外部世界就有可能訪問同一個對象。 但是您不會訪問對該對象的相同引用。
只是為了完整性,根據編譯器,技術上可以訪問 lambda 的內部成員並修改它們。 雖然這基本上是利用了一個實現細節,但永遠不應該這樣做。 但它確實提供了對 lambda 實現的一些見解。
這是在 GCC 6.3 中
#include <iostream>
using namespace std;
template<typename Lambda>
struct lambda_member : Lambda
{
Lambda& f_;
lambda_member(Lambda& f) : Lambda(f),
f_(f)
{}
auto& get_value1()
{
return f_.__value1;
}
};
int main(){
auto test = [value1 =0]() mutable {value1+=1; return value1;};
lambda_member<decltype(test)> lm{test};
std::cout << test() << std::endl;
std::cout << lm.get_value1() << std::endl;
lm.get_value1() = 22;
std::cout << test() << std::endl;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.