[英]Capturing a static variable by reference in a C++11 lambda
我正在嘗試使用GCC 4.7.2編譯以下代碼:
#include <iostream>
int foo() {
static int bar;
return [&bar] () { return bar++; } (); // lambda capturing by reference
}
int main (int argc, char* argv[]) {
std::cout << foo() << std::endl;
return 0;
}
似乎進展不順利,因為輸出是這樣的:
$p2.cpp: In function ‘int foo()’:
$p2.cpp:6:14: warning: capture of variable ‘bar’ with non-automatic storage duration [enabled by default]
$p2.cpp:4:16: note: ‘int bar’ declared here
所以,我的第一個問題是:
這是GCC的失敗,還是代碼不合法C ++ 11? 這在GCC的最新版本中是否已修復?
我考慮使用非文字靜態變量構建基於此原理的工件。 此工件旨在成為shared_ptr <T>對象的工廠,當您只需要為同一實例使用重復的shared_ptr容器時,它可以避免創建新的T對象。
這個工件看起來像:
std::shared_ptr<Foo> create(std::string name) {
static std::unordered_map<std::string,std::weak_ptr<Foo>> registry;
if (auto it = registry.find(name) != registry.end())
return registry[name].lock();
auto b = std::shared_ptr<Foo>(
new Foo(name),
[®istry] (Foo* p) {
registry.erase(p->getName());
delete p;
});
registry.emplace(name,b);
return b;
}
據我所知,如果之前討論的GCC問題在C ++ 11一致性方面不是問題,那么這個工件也不應該成為問題。 使用此hack唯一要注意的是,不要將生成的shared_ptr <T>對象設置為可以在靜態變量之后被破壞的任何全局對象。
我這是對的嗎?
為什么你甚至試圖捕捉bar
? 這是靜態的。 您根本不需要捕獲它。 只需要捕獲自動變量。 Clang會對您的代碼產生嚴重錯誤,而不僅僅是警告。 如果你只是從lambda捕獲中刪除&bar
,那么代碼就能完美運行。
#include <iostream>
int foo() {
static int bar;
return [] () { return bar++; } (); // lambda capturing by reference
}
int main (int argc, char* argv[]) {
std::cout << foo() << std::endl;
std::cout << foo() << std::endl;
std::cout << foo() << std::endl;
return 0;
}
版畫
0
1
2
按照標准,你只能捕捉自動存儲時間(或變量this
,這是因為明確提到可拍攝)。
所以,不,你不能按照標准這樣做(或者,回答你的第一個問題,那不是有效的C ++ 11而不是編譯器錯誤)
5.1.1 / 2 lambda-capture中的名稱應在lambda表達式的上下文中,並且應為此或引用具有自動存儲持續時間的局部變量或引用。
編輯:而且,正如Kevin所說,你甚至不需要捕獲本地static
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.