Variadics
C++0x offers two different type-safe ways of dealing with variable numbers of arguments. One of them lets you give a collection of values of the same type as a single function argument; the other lets you give values of different types as separate arguments to template functions.
Giving a collection of values to a single function argument is what allows declarations such as
vector<int> v = { 3, 1, 4, 1, 5, 9 }; // New in C++0x, v has 6 elements
Under the hood, the standard-library vector code looks something like this:
template<class T> class vector {
public:
vector(initializer_list<T>);
// …
};
The initializer_list template is built into the language. This constructor is used when we provide initializers inside curly braces. In the initialization of v, the compiler collects the values inside the braces, creates an object of type initializer_list<int>, and passes that object to the vector constructor. Within the constructor, the initializer_list object looks like a simplified container with begin and end members that vector can use to initialize its object with the values that the programmer supplied.
The other way to deal with variable numbers of arguments is with a variadic template:
template<class T...> void f(T... args);
This declaration effectively defines an overloaded family of functions:
void f();
template<class T1> void f(T1 arg1);
template<class T1, class T2> void f(T1 arg1, T2 arg2);
// and so on
The author of f can find out how many arguments f has, can forward those arguments to another function, and can process each argument independently, using overloading to check each argument's type during compilation. Unfortunately, the techniques for doing this need far more space than we have available at the moment; so we shall put off the detailed discussion for another day.
Conclusion
C++ has always tried to let programmers write libraries of useful algorithms, data structures, and interfaces. We have tried to give an idea of a few of the important ways in which C++0x continues this trend:
- When we initialize a variable, the compiler can figure out its type for us.
- We can extract type information from declarations and use it in other contexts.
- We can initialize library types as conveniently as built-in types.
- Smart pointer classes make memory allocation much easier.
- Lambda expressions can substitute for simple functions or function objects.
- Classes can arrange to move data without copying it.
- Constructors are easier to write and offer more detailed control.
- We can define functions with varying numbers of arguments and templates with varying numbers of type parameters.
This list barely scratches the surface. However, we believe that these features are among the most important, and that each of them will simplify C++ programming in a significant way.


