簡體   English   中英

lambda表達式中ref-captured和非顯式捕獲的constexpr變量之間的區別

[英]Difference between ref-captured and non-explicitly captured constexpr variables in lambda-expressions

這個問題在沒有捕獲的情況下訪問lambda表達式中的constexpr變量回答了為什么下面示例中的ref-capture不是嚴格必要的。 但另一方面,如果被捕獲,則會收到錯誤。

錯誤似乎是由foo()的遞歸性質觸發的。

template<typename T>
constexpr int bar(const T& x) { // NOK
//constexpr int bar(T x) { // OK
    return x;
}

template<typename T>
int foo(const T& l) {
    constexpr auto x = l() - 1;
    auto y = [&]{return bar(x);}; // if ref-capture is used, the above bar(const T&) is NOK, why? 

    if constexpr(x <= 0) {
        return 42;
    }
    else {
        return foo(y);
    }
}

auto l2 = []{
    return 3;
};

int main() {
    foo(l2);
}

如果我們使用clang作為編譯器,在語言律師方面通常比gcc更相關,我們發現一個簡單的例子非常有說服力:

template<typename T>
int foo(T/*&*/ l) {
    constexpr auto x = l() - 1;

    if constexpr(x <= 0) {
        return 42;
    }
    else {
        return 0;
    }
}

auto l2 = []{
    return 3;
};

int main() {
    foo(l2);
}

foo()簽名中添加和刪除引用會使程序編譯或非編譯。 我相信,這與關於cppreference的常量表達主題的子彈12有關:

一個id-expression引用一個變量或一個引用類型的數據成員,除非它是用一個常量表達式初始化的,或者它的生命周期是在這個表達式的評估中開始的

https://en.cppreference.com/w/cpp/language/constant_expression

所以這兩個陳述似乎都不滿意,因為參考文獻沒有用常量表達式初始化,並且它的生命周期並不是從表達式的評估開始的。

暫無
暫無

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

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