簡體   English   中英

全局與局部函數對象

[英]Global vs. local function object

我有一個返回另一個函數的函數,該函數捕獲包裝器函數的參數。 本地版本有效,但全局版本無效,我不明白為什么:

#include <iostream>
#include <sstream>
#include <iomanip>


const auto& parseDateTimeWithFormat = [](const std::string& formatStr) {
    return [&formatStr](const std::string& dateTimeStr) {
        std::cout << formatStr << std::endl;
        tm t = {};
        std::istringstream ss(dateTimeStr);
        ss >> std::get_time(&t, formatStr.c_str());
        const int timestamp = (int)mktime(&t);
        return timestamp;
    };
};


const auto& parseDateTime1 = parseDateTimeWithFormat("%Y-%m-%dT%H:%M:%SZ");


int main(int argc, const char* argv[]) {
    int ts1 = parseDateTime1("2018-10-08T10:09:08Z");
    std::cout << ts1 << std::endl;

    const auto& parseDateTime2 = parseDateTimeWithFormat("%Y-%m-%dT%H:%M:%SZ");
    int ts2 = parseDateTime2("2018-10-08T10:09:08Z");
    std::cout << ts2 << std::endl;

    return 0;
}

輸出:

(empty string)
-1
%Y-%m-%dT%H:%M:%SZ
1538989748

同樣,當按值而不是按引用捕獲formatStr時,全局版本也適用。

您的本地版本可能“有效”,但它也遭受與全局版本相同的問題,這是未定義的行為。 在所有情況下,當您調用parseDateTimeWithFormat時,都將給出字符串文字。 由於這不是std::string會為您創建一個臨時的。 該字符串就是您捕獲的內容

return [&formatStr](const std::string& dateTimeStr) {
    std::cout << formatStr << std::endl;
    tm t = {};
    std::istringstream ss(dateTimeStr);
    ss >> std::get_time(&t, formatStr.c_str());
    const int timestamp = (int)mktime(&t);
    return timestamp;
};

然后返回lambda。 不幸的是,一旦表達式結束,在您調用parseDateTimeWithFormat地方結束后,該臨時文件便被銷毀,並且剩下對formatStr的懸掛引用。 就像您發現的那樣,解決方法是按值捕獲,因此lambda具有其自己的副本,並且您不會嘗試引用不再存在的內容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM