skip to main |
skip to sidebar
GCC developers, February 2008:
We have implemented the complete specification of variadic templates in the
GNU C++ compiler [8], which are available in GCC 4.3. The implementation itself
was relatively straightforward in GCC, implying that this feature can be implemented
in other C++ compilers without architectural changes. Our basic implementation
approach involved adding flags to each kind of template parameter and
each function parameter stating whether these parameters are in fact parameter
packs.
...
Microsoft guys, September 2011:
We've developed a new scheme for simulating variadic templates.
Previously in VC9 SP1 and VC10, we repeatedly included subheaders with
macros defined differently each time, in order to stamp out overloads
for 0, 1, 2, 3, etc. arguments. (For example, included
the internal subheader repeatedly, in order to stamp out make_shared(args, args, args).)
In VC11, the subheaders are gone. Now we define variadic templates
themselves as macros (with lots of backslash-continuations), then expand
them with master macros. This internal implementation change has some
user-visible effects. First, the code is more maintainable, easier to
use (adding subheaders was a fair amount of work), and slightly less
hideously unreadable. This is what allowed us to easily implement
variadic emplacement, and should make it easier to squash bugs in the
future. Second, it's harder to step into with the debugger (sorry!).
Third, pair's pair(piecewise_construct_t, tuple, tuple)
constructor had "interesting" effects. This requires N^2 overloads (if
we support up to 10-tuples, that means 121 overloads, since empty
tuples count here too). We initially observed that this (spamming out
so many pair-tuple overloads, plus all of the emplacement overloads)
consumed a massive amount of memory during compilation, so as a
workaround we reduced infinity. In VC9 SP1 and VC10, infinity was 10
(i.e. "variadic" templates supported 0 to 10 arguments inclusive). In
the VC11 Developer Preview, infinity is 5 by default. This got our
compiler memory consumption back to what it was in VC10. If you need
more arguments (e.g. you had code compiling with VC9 SP1 or VC10 that
used 6-tuples), there's an escape hatch. You can define _VARIADIC_MAX
project-wide between 5 and 10 inclusive (it defaults to 5). Increasing
it will make the compiler consume more memory, and may require you to
use the /Zm option to reserve more space for PCHes.