I have the following code that is (for demonstration purposes) supposed to assert that all arguments evaluate to true using C++17 fold expressions.
#include <cassert>
template<typename... Ts>
void fn(Ts... ts)
{
assert(ts && ...);
}
int main()
{
fn(true, true, true);
fn(true, true, false, true);
}
On Coliru it works as expected; it does not on my machine. I get the error
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 && ...);
^~~~~~
with gcc version 8.2.1 20180831. On Ubuntu with gcc version 5.4.0 20160609 I get
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’
Here is a table of where it worked and where it didn't with the corresponding compiler versions.
| 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) |
Since it works/fails so arbitrarily I feel like this is a problem with the standard library and clang by default uses libstdc++, I believe, which would explain why it either works or doesn't work for both on a system.
Should this code compile? If yes, how do I make it work? If no, is it a compiler bug?
PS: On Coliru I have been able to use quite complex folding expressions, but I have not tried others on other machines.