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

Fold expressions and empty parameters pack: what's the expected result?


Consider the following minimal example:

#include<cstddef>

template<std::size_t... I>
constexpr auto sum() { return (I + ...); }

template<bool... B>
constexpr auto check() { return (B && ...); }

int main() {
    static_assert(6 == sum<1,2,3>(), "!");
    // static_assert(0 == sum<>(), "!");
    static_assert(check<true, true>(), "!");
    static_assert(check<>(), "!");
}

The commented line doesn't compile.
The same applies using * instead of +.
The one involving booleans works instead.

Here (working draft) I haven't found mentions about empty parameter packs.
On the other side, here (isocpp) it seems that the default result in the case above is int().

What's exactly the expected behavior when mixing fold expressions and an empty parameters pack?


Solution

  • This is covered in [temp.variadic]¶9 (citing N4618):

    If N is zero for a unary fold-expression, the value of the expression is shown in Table 14; if the operator is not listed in Table 14, the instantiation is ill-formed.

    Table 14 — Value of folding empty sequences:

    Operator  |  Value when parameter pack is empty  
    -----------------------------------------------
    &&        |  true
    ||        |  false
    ,         |  void()
    

    The reason only these three operators are supported is outlined in P0036R0.