在最近的C++ 0x草案(n3225.pdf)之一,我們可以發現5.1.2/10:瞭解的C++ 0x的λ捕獲
在捕獲列表的標識符擡頭使用通用規則進行非限定名稱查找(3.4.1);每個這樣的查找應該在本地lambda表達式的範圍內找到一個具有自動存儲持續時間的變量。如果一個實體(即一個變量或這個)出現在lambda表達式的捕獲列表中,則被認爲是顯式捕獲的。
這似乎相當嚴格的給我。例如,它似乎向我下面的事情是不允許的:
int global;
struct s {
int x;
void memfun() {
[x,global]{};
}
};
因爲x
不一定與自動存儲一個變量,也不是global
。請注意,此捕獲條款的目的是讓lambda對象存儲副本的x
和global
,這些副本在稍後階段進行更改時可能需要。我已經知道一種替代的:
int global;
struct s {
int x;
void memfun() {
int copyx = x;
int copyglobal = global;
[copyx,copyglobal]{};
}
};
但這歸結爲額外的拷貝和額外的鍋爐板只是捕捉x
和global
的副本。
而且,我無法找到任何東西一下如果我們將其命名捕獲子句中的本地引用會發生什麼最新的草案結論:
int main() {
int i = 0;
int &r = i;
assert([r]{return &r;}() != &i);
}
是否拉姆達對象「複製一個參考」或「複製一個int 「?如果它通過複製捕獲被引用的對象,這可以爲我們節省以前解決方法的額外副本。
GCC顯然支持所有這些例子,並在最後一種情況下存儲一個int的副本(這是可取的,恕我直言)。但是我想知道這是否實際上是根據C++ 0x草案的預期行爲,還是僅僅是一個編譯器擴展,實際上是一個實現錯誤。
編輯:
templatetypedef指出5.1.2/14這也說明當參考在捕獲子句被命名爲會發生什麼。據我所知,這讓我們可以使用下面的變通的第一個例子:
int global;
struct s {
int x;
void memfun() {
auto& cx = x;
auto& cglob = global;
[cx,cglob]{};
}
};
蒂亞, sellibitze
注意:C++ 14擴展了可能的捕獲子句集合 – sellibitze 2014-07-01 14:13:44