GCC 以错误的方式解包(我<...)折叠表达式

GCC unpacks (I < ...) fold expression the wrong way

本文关键字:lt 表达式 折叠 错误 方式解 GCC      更新时间:2023-10-16

我已经向GCC打开了一个错误,但我想知道我的期望是否正确。

考虑此建议和以下折叠表达式:

(args < ...)

它应该等效于:

((args$0 < args$1) < ...) < args$n

请考虑以下代码:

#include <cassert>
int main() {
    assert((0 < 42) < 3);
}

断言编译并正常工作,它不会失败(正如预期的那样,请注意结果不是((0 <42)和(42 <3)),表达式本身非常不寻常且毫无意义)。
另一方面,当使用折叠表达式时:

template<int... I>
static constexpr bool f() {
    return (I < ...);
}
int main() {
    static_assert(f<0, 42, 3>(), "!");
}

断言在编译时失败 (GCC 6.1.0)。
我希望它能够编译,因为提案中包含的内容。
它应该成功,因为它等效于上面不涉及折叠表达式的示例。
解压缩的表达式确实应该是:((0 <42) <3)。

我是对的还是我在这里错过了一些关于折叠表达式的重要内容?

N4191是最初的提案。GCC 的 C++1z 状态页面指出,它在 N4295 中实施了修订后的提案。

左右折叠的规则发生了变化,我相信您的代码现在需要生成右折叠,即 0 < (42 < 3),这是false

I < ...是右折; ... < I将是左折。