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).
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;
}