[英]Type deduction for variable declared in lambda's capture
在這個片段中,我在 lambda 的捕獲中聲明了一個變量i
。
int main()
{
vector<int> vec;
// Pushing 0-99 numbers to vector
std::generate_n(std::back_inserter(vec), 100, [i = 0]() mutable { return i++; });
return 0;
}
如你所見,沒有任何地方為i
聲明類型。
據我所知,我可以用這種方式編寫等效的功能:
int main()
{
vector<int> vec;
// Pushing 0-99 numbers to vector
std::generate_n(std::back_inserter(vec), 100, [](){
static int i = 0;
return i++; });
return 0;
}
編譯器如何知道第一個例子中i
的類型? 它是從我對其執行的操作中推導出來的 (++) 嗎? 它是否知道它是int
因為容器?
使用 -std=c++14 和 -std=c++17 使用 GCC 進行編譯時沒有任何抱怨。 盡管如此,如果我使用 -std=c++11 進行編譯,則會收到以下警告:
lambda_test.cpp: In function ‘int main()’:
lambda_test.cpp:24:51: warning: lambda capture initializers only available with -std=c++14 or -std=gnu++14
std::generate_n(std::back_inserter(first), 100, [i = 0]() mutable { return i++; });
^
更多:鑒於評論,我試圖查看編譯器為 c++11 和 14 生成的內容的差異,但它生成相同的代碼: https : //cppinsights.io/s/43411e6f
正如錯誤所說,您必須激活 C++14 才能使 lambda 捕獲初始值設定項工作,因為它是在 C++14 中添加的。
據我所知,我可以用這種方式編寫等效的功能:
不,靜態存儲在功能上是不同的。 使用捕獲,您可以復制 lambda,它將復制捕獲的狀態。 使用靜態變量,每個 lambda 訪問相同的全局變量。
編譯器如何知道第一個例子中 i 的類型? 它是從我對其執行的操作中推導出來的 (++) 嗎? 它是否知道它是 int 因為容器?
不,因為許多類型都有 ++ 運算符。
編譯器簡單地使用初始化器來推斷類型。 你可以看到它好像那里有一個隱藏的auto
:
std::generate_n(std::back_inserter(vec), 100, [/* auto */ i = 0]() mutable { return i++; });
文字0
是int
類型。 所以i
是一個int
。
從技術上講,您也可以這樣做:
std::generate_n(std::back_inserter(vec), 100, [/* auto */ i = 0ull]() mutable { return i++; });
然后i
有unsigned long long
類型,因為文字0ull
是那種類型。
它的工作原理就像你做的那樣
auto i = 0;
如果您不捕獲現有變量並且該初始化器用於確定類型,則必須指定一個初始化器。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.