我有以下代码(出于演示目的)应该声明所有参数都使用C++ 17折叠表达式评估为true。

#include <cassert>

template<typename... Ts>
void fn(Ts... ts)
{
    assert(ts && ...);
}

int main()
{
    fn(true, true, true);
    fn(true, true, false, true);
}

在Coliru上,它可以按预期工作;它不在我的机器上。我得到错误
In file included from /usr/include/c++/8.2.1/cassert:44,
                 from foldexpr.cpp:1:
foldexpr.cpp: In function ‘void fn(Ts ...)’:
foldexpr.cpp:6:15: error: expected ‘)’ before ‘&&’ token
     assert(ts && ...);
               ^~
foldexpr.cpp:6:5: error: expected ‘;’ before ‘)’ token
     assert(ts && ...);
     ^~~~~~

使用gcc版本8.2.1 20180831.在使用gcc版本5.4.0 20160609的Ubuntu上
In file included from /usr/include/c++/5/cassert:43:0,
                 from foldexpr.cpp:1:
foldexpr.cpp: In function ‘void fn(Ts ...)’:
foldexpr.cpp:6:18: error: expected primary-expression before ‘...’ token
     assert(ts && ...);
                  ^
foldexpr.cpp:6:18: error: expected ‘)’ before ‘...’ token
foldexpr.cpp:6:22: error: expected ‘)’ before ‘;’ token
     assert(ts && ...);
                      ^
foldexpr.cpp:6:22: error: parameter packs not expanded with ‘...’:
foldexpr.cpp:6:22: note:         ‘ts’

这是一张表格,列出了它在哪些地方有效以及在相应的编译器版本中无效。
| OS              | GCC               | Clang             |
|-----------------|-------------------|-------------------|
| Arch            | no (v8.2.1)       | no (v7.0.0)       |
| Ubuntu (Coliru) | yes (v8.1.0)      | yes (v5.0.0)      |
| Debian          | yes (v6.3.0)      | -                 |
| ? (Godbolt)     | no (all versions) | no (all versions) |

由于它如此随意地工作/失败,我认为这是标准库的问题,并且默认情况下clang使用libstdc++,我相信,这将解释为什么它在系统上既不能工作又不能工作。

该代码应该编译吗?如果是,我如何使其工作?如果不是,那是编译器错误吗?

PS:在Coliru上,我已经可以使用非常复杂的折叠表达式,但是我没有在其他机器上尝试过其他折叠表达式。

最佳答案

折叠表达式必须采用以下形式:

( pack op ... )
( ... op pack )
( pack op ... op init )
( init op ... op pack )

您的
assert(ts && ...)

不遵循该要求,它缺少括号。你需要
assert((ts && ...))

使它在语法上正确。

09-05 03:20