C++ varargs - Is how I am using them okay or are they bad? Is there a good alternative?

c++, c++11, variadic-functions, visual-studio-2010

Solution

What you want is `std::initializer_list<T>`, unfortunately this require C++11 support.

An alternative, that is nearly as elegant and easy enough to upgrade from, is to use an array:

#include <iostream>
 
template <typename T, size_t N>
void func(T (&s)[N]) {
    for (size_t i = 0; i != N; ++i) {
        std::cout << s[i] << '\n';
    }
}
 
int main() {
    int array[] = {1, 2, 3};
    func(array);
}

When you move on to a compiler that supports initializer lists, this can be changed into:

#include <iostream>
 
template <typename T>
void func(std::initializer_list<T> s) {
    for (T const& t: s) {
        std::cout << t << '\n';
    }
}
 
int main() {
    func({1, 2, 3});
}

So both the function and call sites update will be painless.

Note: the call site could be made completely similar using a macro, I advise against such approach, the purported gain is not worth the obfuscation.

Problem

The ultimate goal of this is to have a function which can take a variable number of arguments of a certain type (the same type, not different types), that can be declared on the function call. As I'm using Visual Studio 2010, I CANNOT do: ``` MyFunction({1,2,3}); ``` In an earlier question which was answered, I found I could use `boost::assign::list_of()`, however I discovered later that this seems to have a bug of some kind if you try to pass it only one parameter. So I did some more searching and found that I could use variadic functions to achieve what I was aiming for. ``` void TestFunction2<int>(int count, ...) {} ``` However, I wanted to restrict it by type, so eventually found I could do this with templates: ``` template <class T> void TestFunction(const T& count, ...); template <> void TestFunction<int>(const int& count, ...); ``` Unfortunately, varargs things like `va_list` do not apparently like references. The examples I saw to restrict types like this used const references. If I remove the const reference aspect of the count parameter, it works as I want, but I don't know if this is going to lead to horrible side-effects down the road, OR if this whole varargs thing is a bad idea to begin with. So I guess my question is, is what I'm doing in the last example above good or bad? If it's bad, what is a good alternative so I can call a function with one or more parameters in-line like, say, `int` parameters?

Original source

Related problems