1

I'm not understanding why this is not working:

template <typename ... Types>
void func()
{

    (std::cout << typeid(Types).name(), ...) ; // Syntax error, unexpected token '...', expected 'expression'
    (static_assert(std::is_integral_v<Types>, "Type must be integral type"), ...); // Syntax error: unexpected token 'static_assert', expected 'expression'
}
int main()
{
    func<int, short>();

}

My understanding is that the compiler should basically go:

(static_assert(std::is_integral_v<Types>, "Error message"), ...)

The comma is an operator and what's before the operator should get repeated for each type in the parameter pack. Why isn't this working?

underscore_d
  • 6,309
  • 3
  • 38
  • 64
Zebrafish
  • 11,682
  • 3
  • 43
  • 119

3 Answers3

3

Fold expressions can't contain (unparenthesized) operators with precedence lower than that of a cast.

So either add parentheses: ((std::cout << typeid(Types).name()), ...);

Or fold over << instead: (std::cout << ... << typeid(Types).name());


As for static_assert, it's a declaration rather than an expression, so you can't fold it.

Use one big static_assert, with a &&-fold expression:

static_assert((std::is_integral_v<Types> && ...), "Type must be integral type")
HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207
2

Operator << requires ... to be placed inbetween operators. static_assert is not an expression and therefore fold expression won't help. The workaround is to create a dedicated check function with a single static_assert and invoke this function folding built-in operator , invocations:

#include <iostream>
#include <typeinfo>
#include <type_traits>

template<typename x_Type>
constexpr void is_integral_check(void) noexcept
{
    static_assert(::std::is_integral_v<x_Type>, "Type must be an integral type.");
    return;
}

template<typename ... x_Types>
void func()
{
    (::std::cout << ... << typeid(x_Types).name());
    (is_integral_check<x_Types>(), ...);
}

int main()
{
    func<int, short>();
}

https://godbolt.org/z/5G4xxc15s

user7860670
  • 35,849
  • 4
  • 58
  • 84
1

You first syntax error my be the result of not using C++17 as fold expression were introduced there. I tried to compile your code with C++14 and got the same syntax error.

(std::cout << typeid(Types).name(), ...);  // needs C++17, Syntax error with C++14

The second one can be rewritten like this:

static_assert((std::is_integral_v<Types> && ...), "Type must be integral type");
ccdMuro
  • 229
  • 2
  • 5