簡體   English   中英

`if constexpr`,內部lambda,內部包擴展 - 編譯器bug?

[英]`if constexpr`, inside lambda, inside pack expansion — compiler bug?

clang version 5.0.0 (trunk 305664)
Target: x86_64-unknown-linux-gnu

以下代碼成功編譯:

template <int... A>
void f() {
    ([](auto) {
        if constexpr (A == 0)
            return 42;
        else
            return 3.14;
    }(0), ...);
}

int main() {
    f<0, 1>();
}

......但是這個沒有:

template <int... A>
void f() {
    ([](auto...) {            // Variadic lambda
        if constexpr (A == 0)
            return 42;
        else
            return 3.14;
    }(), ...);                // No argument
}

int main() {
    f<0, 1>();
}

...屈服:

<source>:7:13: error: 'auto' in return type deduced as 'double' here but deduced as 'int' in earlier return statement
            return 3.14;
            ^
<source>:3:6: note: in instantiation of function template specialization 'f()::(anonymous class)::operator()<>' requested here
    ([](auto...) {            // Variadic lambda
     ^
<source>:12:5: note: in instantiation of function template specialization 'f<0, 1>' requested here
    f<0, 1>();
    ^

我不希望在空參數包和偽參數之間有不同的行為。

是否存在這種差異的原因,或者這是編譯器錯誤?

我相信這是一個鏗鏘的錯誤。

[dcl.spec.auto]中的規則強調我的:

如果函數的聲明返回類型包含占位符類型,則函數的返回類型是從函數體([stmt.if])中的非丟棄 return語句(如果有)推導出來的。

[...]

如果具有包含占位符類型的聲明返回類型的函數具有多個非廢棄的 return語句,則會為每個此類返回語句推斷返回類型。 如果推斷的類型在每次扣除中不相同,則該程序是不正確的。

lambda中的一個或另一個return語句被丟棄( if constexpr被稱為丟棄語句if constexpr取非分支),只留下一個非丟棄的return語句,因此lambda的返回類型應該簡單地從中推斷出來。一個遺留下來。

此外,clang還可以這樣:

template <int A>
void f() {
    [](auto...) {
        if constexpr (A == 0)
            return 42;
        else
            return 3.14;
    }();
}

int main() {  
    f<0>();
    f<1>();
}

所以這可能與lambdas在包表達式中的工作方式有一些不良的交互。

暫無
暫無

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

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