Search code examples
c++variadic-templatesvariadic-functions

How iteration over parameter pack going through initializer_list?


Sorry for being vague with my question, but I just don't understand what does this function does and how. Code from here:

template<typename ... T>
auto sum (T ... t)
{
    typename std::common_type<T...>::type result{}; //zero-initialization?
    (void)std::initializer_list<int>{(result += t, 0)...}; //why 0 is here
    return result;
}

I don't know why but this piece of code seems so odd, it don't look like C++ to me. Semantically, this function sums all the parameters in a result variable, obviously. But I completely do not understand why it was written that way. Using initializer_list here seem like a trick to trigger iteration over arguments in parameter pack but still...

Why initializer_list is explicitly was cast to void? To not take up extra memory?

And how iteration over parameter pack is going? Why not for example (void)std::initializer_list<int>{(result += t)...}; (it does not compile by the way).


Solution

  • Thanks to the comments, I figured out the answer.

    I haven't ever come across comma operator, so the line (result += t, 0) made to me no sense until your comments about EXISTENCE of comma operator and this question. So basically we initializing our list with zeros. And since I made type of initializer_list for integers, I can't write (void)std::initializer_list<int>{result += t...}, since returning value of result += t is int& not int.

    So why don't we write (void)std::initializer_list<int&>{result += t...}? It doesn't compile, and I suspect that because array of references is forbidden in C++. So here's the solution to my problem:

    template <typename ... T>
    auto sum1(T ... t)
    {
        std::common_type_t<T...> tmp{};
        std::initializer_list<std::reference_wrapper<std::common_type_t<T...>>>{tmp += t...};
        return tmp;
    }