Search code examples
c++c++17variadic-templatestemplate-meta-programmingfold-expression

How to use if constexpr in template fold expressions?


I would like to write a sum function with variable number of argument with the condition that it should ignore argument that are not std::is_arithmetic

I have figured out a recursive version that works

auto old_sum(){
    return 0;
}

template<typename T1, typename... T>
auto old_sum(T1 s, T... ts){
    if constexpr(std::is_arithmetic_v<T1>)
        return s + old_sum(ts...);
    else
        return old_sum(ts...);
}

I am wondering if I can use the if constexpr in the context of fold expression to make the following code only considers arithmetic types from the argument pack:

template<typename... T>
auto fold_sum(T... s){
    return (... + s);
}

Solution

  • As we do not have a ternary constexpr operator, we can use a lambda instead.

    #include <type_traits>
    
    template<typename... T>
    constexpr auto fold_sum(T... s){
        return (... + [](auto x)
        {
            if constexpr(std::is_arithmetic_v<T>) return x;
            else return 0;
        }(s));
    }
    

    Usage:

    int main()
    {
        static_assert(fold_sum(0, nullptr, 5, nullptr, 11, nullptr) == 16);
    }
    

    live example on godbolt.org