`如果constexpr`,在lambda里面,包内部扩展
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的未采用分支称为废弃语句),只留下一个未丢弃的返回语句,所以lambda的返回类型应简单地从该语句中推导出来一个留下。 
此外,铿锵可以这样做:
template <int A>
void f() {
    [](auto...) {
        if constexpr (A == 0)
            return 42;
        else
            return 3.14;
    }();
}
int main() {  
    f<0>();
    f<1>();
}
所以这可能与lambda表达式中的lambdas工作有些不好的相互作用。
链接地址: http://www.djcxy.com/p/39831.html上一篇: `if constexpr`, inside lambda, inside pack expansion
下一篇: How to reset the state of a StackNavigator nested in a DrawerNavigatior?
