6

Does passing multiple arguments via ::std::initializer_list offer any advantages over the variadic function template method?

In code:

template <typename T> void f(::std::initializer_list<T> const);

template <typename ...A> void f(A&& ...args);

Note that the types A... can be restricted to a single type as well, through SFINAE or static_assert(). The arguments can be iterated through ...

user1095108
  • 14,119
  • 9
  • 58
  • 116
  • 1
    Possible duplicate: [Why use variadic arguments now when initializer lists are avaiable?](http://stackoverflow.com/questions/15465543/why-use-variadic-arguments-now-when-initializer-lists-are-avaiable) – NathanOliver May 10 '16 at 13:06
  • 3
    Unclear what you are asking. initializer list allows you to pass a number of arguments of the same type by value. template function allows you to pass a number of (differently) typed arguments by forwarding reference. Those two are very different. – SergeyA May 10 '16 at 13:11
  • @NathanOliver You should read my question more carefully. – user1095108 May 10 '16 at 13:13
  • @SergeyA The types can be restricted to a single type via static_assert and SFINAE, read read read my question again, reread. – user1095108 May 10 '16 at 13:15
  • 1
    I have read it 3 times. I am still unclear what the question is. – SergeyA May 10 '16 at 13:19
  • 1
    The keyword being *can*. You *can* limit the variadic argument pack, but you don't *have* to. And *if* you limit the type, then you have the whole forwarding references bit too. If you want to pass a number of different arguments of different types, use parameter packs. If you want to pass a set of values of the same type, you can use `std::initializer_list`, or vectors, or arrays, or parameter packs as well. You also need to know if you want to iterate over the values. It all have to do with your use-cases, your design, and what problem you are actually trying to solve. – Some programmer dude May 10 '16 at 13:22
  • @user1095108: I think you mean to ask about the advantages/disadvantages for passing a sequence of arguments of the same type? – Cheers and hth. - Alf May 10 '16 at 13:23
  • @user1095108 I did read the question. That is why I did not use my hammer and instantly close the question. I merely suggested it and if others feel it is appropriate they can vote to close. – NathanOliver May 10 '16 at 13:38
  • @Cheersandhth.-Alf No, this flexibility could be thought of as an advantage. The idea is, that I'm deeply suspicious of the initializer lists, I think they are inferior to the variadic template method. – user1095108 May 10 '16 at 13:39
  • The advantage that the size must not be a compile time constant? And the disadvantage that you don't anymore have a vanilla function call syntax with `f({ .. })` and that all elements must be the same size and that you can't move? Err, these two have completely different purposes, and initializer lists should almost be never used by user-functions. Reserve them for class member functions that have something to do with sequences of variable size. – Johannes Schaub - litb May 11 '16 at 17:22
  • [this doc](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2772.pdf) should be helpful. It compared both solutions, and did some benchmarks. – for_stack Feb 26 '18 at 02:55

3 Answers3

4

There are advantages to having an initializer_list<T> instead of a variadic template, assuming that either one would solve the problem.

For example, function definitions can only have so many parameters, even variadic ones. Implementations are allowed to have a hard limit, and the standard only requires that limit to be at least 256. The same goes for parameters in a function call.

By contrast, the number of values in a braced-init-list has a minimum limit of 16K (and implementations will usually permit far more). So if it's reasonable for the user to be calling this function with a gigantic set of values, initializer_list is the only one where you can expect a compiler to work.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
3

You can iterate over an std::initializer_list in a way that you cannot over a parameter pack (unless you have C++17 and you fold it first). So for example you can have for loops with the lists. With parameter packs, you only option to expand them is via recursive specialised definitions.

Smeeheey
  • 9,906
  • 23
  • 39
1

On occasions I had used variadic template functions just like yours, but then realized that I needed more parameters, possibly templated. In that case typename... A is too eager, and I was happy to rely on braces on the call site to clearly specify where the variadic list of arguments ends, and where the following optional arguments started.

akim
  • 8,255
  • 3
  • 44
  • 60