Variadic Templates for GCC

Douglas Gregor, Indiana University < >

News

March 9, 2007 : Variadic templates are now available in the GCC Subversion repository, as part of the experimental C++0x mode that will debut in GCC 4.3. With this, I will no longer be maintaining the GCC 4.1.x version of variadic templates.

: Variadic templates are now available in the GCC Subversion repository, as part of the experimental C++0x mode that will debut in GCC 4.3. With this, I will no longer be maintaining the GCC 4.1.x version of variadic templates. December 5, 2006 : Draft wording for the changes to the C++0x language and standard library are now available in the documentation section.

: Draft wording for the changes to the C++0x language and standard library are now available in the documentation section. November 1, 2006 : Version 1.5 of the variadic templates implementation in GCC is now available for download. This version introduces several bug fixes, new features, and one syntax change, including: The syntax for determining the length of a parameter pack has changed. Instead of sizeof(Args...) we now use sizeof...(Args) , which should be less confusing. One can now expand parameter packs in base classes and initializers of those base classes, e.g., template struct myclass : public Mixins... { myclass(const Mixins&... mixins) : Mixins(mixins)... { } }; One can now expand parameter packs in a throw specifier. One can now expand parameter packs in initializer list., e.g., template void foo(const Values&... values) { boost::any array[sizeof...(Values)] = { values... }; // ... }

: Version 1.5 of the variadic templates implementation in GCC is now available for download. This version introduces several bug fixes, new features, and one syntax change, including:

Introduction

Variadic templates allow a C++ template to accept an arbitrary number of "extra" template arguments. When used with class templates, we can write templates like tuple (a generalized pair), or arbitrary-level compile-time vectors for template metaprogramming. Variadic templates also work in conjunction with function templates, so that function templates can take an arbitrary number of function arguments. In this sense, variadic templates provide the same capabilities as C's variadic functions, but in a type-safe manner. For instance, one can implement a simple, type-safe printf with the following code:

void printf(const char* s) { while (*s) { if (*s == '%' && *++s != '%') throw std::runtime_error("invalid format string: missing arguments"); std::cout << *s++; } } template void printf(const char* s, const T& value, const Args&... args) { while (*s) { if (*s == '%' && *++s != '%') { std::cout << value; return printf(++s, args...); } std::cout << *s++; } throw std::runtime_error("extra arguments provided to printf"); }

Motivation

Variadic templates solve some serious limitations in current implementations of certain facilities of the C++ Library Extensions Technical Report (TR1). The function object and tuple facilities, for instance, are only barely implementable in current C++. The implementations are very repetitive, requiring the same code to be copied multiple times (each copy supports a different number of arguments). The need to compile all of these copies can actually be quite taxing. The following chart shows compilation times for the GNU TR1 implementation as we increase the number of supported parameters from 1 to 40.

With variadic templates, compilation takes less than a second, and supports any number of arguments. The code is 50k smaller, much clearer, and does not need to make use of any hideous preprocessor metaprogramming tricks.

Documentation

We hope that variadic templates will be included in the upcoming revision of the ISO C++ standard, dubbed C++0x. The following documents describe variadic templates in more detail.

We welcome your feedback! Give the compiler a spin, or just read through the proposals and tell us what you think! Douglas Gregor, the primary author, can be reached at .