GCC 以错误的方式解压 (I < ...) 折叠表达式
GCC unpacks (I < ...) fold expression the wrong way
我已经向 GCC 开放了 bug,但我想知道我的预期是否正确。
考虑 this 提案和以下折叠表达式:
(args < ...)
它应该等同于:
((args[=11=] < args) < ...) < 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>(), "!");
}
编译时断言 fails (GCC 6.1.0)。
由于提案中包含的内容,我希望它能够编译。
它应该成功,因为它等同于上面不涉及折叠表达式的示例。
解压缩后的表达式确实应该是:((0 < 42) < 3).
我说得对还是我遗漏了一些关于折叠表达式的重要信息?
N4191 是最初的提案。 GCC 的 C++1z status page notes that it implement the revised proposal in N4295.
左右折叠的规则发生了变化,我相信您的代码现在需要生成右折叠,即 0 < (42 < 3)
,即 false
。
I < ...
是右折; ... < I
将是左折。
我已经向 GCC 开放了 bug,但我想知道我的预期是否正确。
考虑 this 提案和以下折叠表达式:
(args < ...)
它应该等同于:
((args[=11=] < args) < ...) < 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>(), "!");
}
编译时断言 fails (GCC 6.1.0)。
由于提案中包含的内容,我希望它能够编译。
它应该成功,因为它等同于上面不涉及折叠表达式的示例。
解压缩后的表达式确实应该是:((0 < 42) < 3).
我说得对还是我遗漏了一些关于折叠表达式的重要信息?
N4191 是最初的提案。 GCC 的 C++1z status page notes that it implement the revised proposal in N4295.
左右折叠的规则发生了变化,我相信您的代码现在需要生成右折叠,即 0 < (42 < 3)
,即 false
。
I < ...
是右折; ... < I
将是左折。