繁体   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