2013-03-01 85 views
1

我有一個函數中的lambda函數用[&]捕獲,然後在lambda中使用局部靜態變量。我不知道這是否有效與開始,但這種編譯和鏈接罰款:未定義的參考在lambda中捕獲靜態變量

void Foo() 
{ 
    static int i = 5; 

    auto bar = [&]() 
    { 
     i++; 
    }; 

    bar(); 
} 

int main() 
{ 
    Foo(); 
} 

但通過使Foo一個模板函數:

template <typename T> 
void Foo() 
{ 
    static int i = 5; 

    auto bar = [&]() 
    { 
     i++; 
    }; 

    bar(); 
} 

int main() 
{ 
    Foo<int>(); 
} 

我得到以下錯誤:

g++-4.7 -std=c++11 main.cpp
/tmp/cctjnzIT.o: In function 'void Foo()::{lambda()#1}::operator()() const':
main.cpp:(.text+0x1a): undefined reference to 'i'
main.cpp:(.text+0x23): undefined reference to 'i'
collect2: error: ld returned 1 exit status

所以,我有兩個問題:

  1. 在第一個例子中使用i即使有效的C++?
  2. 如果#1,那麼第二個例子有什麼問題?或者這是一個gcc錯誤?
+0

從技術上講,只有具有自動存儲持續時間的變量纔會被「捕獲」。在這兩個例子中,對「i」的引用只是一個普通的有效的左值用法。 – aschepler 2013-03-01 19:22:51

回答

-2

1)是的,假設你打算讓'我'的值在呼叫之間持續存在。

2)它不是編譯器中的錯誤。靜態實例變量也需要通過模板來定義。請參閱this post

+0

該帖子是關於靜態類成員,而不是靜態本地函數。我如何明確提及這些? – JaredC 2013-03-01 18:21:00

+0

我想你最終會遇到問題。主要是B/C每個模板專門化時使用它(因此你得到你的靜態變量的多個實例)實例化。 – 2013-03-01 18:30:23