[英]`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.