Search code examples
c++c++17fold-expression

Pass a fold expression to a variadic template


consider the following function that prints the arguments using fold expressions.

template <typename... T>
void print(T &&... t)
{
    (std::cout << ... << t) << '\n';
}

Consider a second function that calls it :

template <typename T, T... vals>
void call_print(std::integer_sequence<T, vals...> &&)
{
    print(vals...); //ok: prints 01234
}
call_print(std::make_index_sequence<5>{});

In my use case, I need to call print this way (with a fold expression)

template <typename T, T... vals>
void call_print2(std::integer_sequence<T, vals...> &&)
{
    print((vals, ...)); //not OK: only prints 4
}
call_print2(std::make_index_sequence<5>{});

In this case the call looks like this

print(0,(1,(2,(3,4))));

but the function seems to be only catching the last argument, as if I called it like so:

print(4);

any help would be appreciated

EDIT: What I am actually trying to accomplish

template<typename T, T ... ints>
auto make_seq(std::integer_sequence<T, ints...>&&)
{
   auto lambda = []<T val>()->T{/*implementation doesn't matter*/};
   return std::integer_sequence<T, (lambda.template operator()<ints>(), ...)>{}; //<- right here
}

Solution

  • print((vals, ...)) expands to print((0, 1, 2, 3, 4)). (0, 1, 2, 3, 4) is an expression using the comma operator. The comma operator evaluates both of its operands and discards the result of the left-hand side of the expression. That means that the expression (0, 1, 2, 3, 4) evaluates to the value 4. Thus print((vals, ...)) is the same as print((0, 1, 2, 3, 4)) is the same as print(4).

    In general, fold expressions are expressions, and thus evaluate to a single value. You need to use a normal parameter pack expansion instead. For example:

    template<typename T, T... ints>
    auto make_seq(std::integer_sequence<T, ints...>&&)
    {
       auto lambda = []<T val>()->T{/*implementation doesn't matter*/};
       return std::integer_sequence<T, lambda.template operator()<ints>()...>{};
    }
    

    Live Demo