Fixed-Parameter Templates
A variadic template, sometimes called a variadic, can accept any number of arguments, so its argument count is set by each call rather than by its declaration.
Why Fixed Parameter Lists Fall Short
Suppose you want one piece of code that works whether a caller passes one value, five values, or none at all. A template that always expects the same fixed list of parameters cannot do this without help. Variadic templates, sometimes just called variadics, solve the problem by accepting a varying number of arguments. That flexibility is the reason to use them, but it also creates a cost that you must understand before using them well.
This article focuses on that cost. The source describes the situation as two-sided. The strength of a variadic template is that it can accept any arguments you care to give it. The weakness is that checking the types of its interface can be a possibly elaborate template program. Keep both halves of that statement in mind as you read, because the rest of the article unpacks each one.
One Slot for a Whole Argument Line
A helpful way to picture a variadic template is as a single slot that takes a whole line of arguments, rather than a row of labeled boxes. Each argument in a call occupies a position in that line. The arguments do not need to share a type, and the number of positions is decided by the call, not by the template's declaration.
The diagram uses a made-up call that passes three arguments to show how positions line up. Notice that the template did not list three positions anywhere. The single slot simply received whatever the call supplied, and the three values landed in three positions because the call supplied three values.
Fixed Versus Variadic Declarations
A variadic template, sometimes called a variadic, is a template that can accept any number of arguments, so its argument count is set by each call rather than by its declaration.
The important word in that definition is any. A variadic template is not limited to one specific argument count. Compare this with a template that declares exactly two parameters. That version can only be used with two arguments. The variadic version can be given two arguments, or ten, or none, as long as the arguments are acceptable to it. The source's phrasing points to breadth in the argument list rather than a fixed shape.
Same Template, Different Calls
Calling one variadic template three ways
A single variadic template is called with one argument, then with several arguments of different kinds, then with none. How does the argument list change, and does the template change?
- 1Call with one argument
The call supplies a single value, so the slot's argument list has a single position.
- 2Call with several mixed arguments
The call supplies, for example, a number, a piece of text, and a true-or-false value. The arguments do not need to share a type, and the list now has one position per argument.
- 3Call with no arguments
The call supplies nothing, so the argument list is empty. The template is still the same declaration.
- 4Compare the three calls
Only the call changed between the three cases. The declaration stayed fixed while the argument count moved from one to several to none. This separation between template and call is what gives variadic templates their reach.
The argument count is set by each call. The template declaration does not name a number, so the same template serves all three calls.
The Cost: Checking the Interface
Flexibility is easy to grant but harder to verify. When a template has a fixed number of parameters, the question of whether a call is acceptable is fairly contained. The caller supplies the expected number of values, and each one is compared against the expected kind. When a template accepts any number of arguments, the set of acceptable calls is open-ended. The template itself therefore has to describe how its interface should be checked for whatever arguments actually arrive.
This is why the source calls type checking of the interface a possibly elaborate template program. Checking is not a single simple comparison that the template gets for free. Instead, the checking is itself written as template code that can be involved in its own right. The word possibly matters: the source says the checking can be elaborate, not that it always is. Some interfaces will be easy to describe, and others will need considerably more template code to verify.
A fixed template pushes most of its rules into a visible parameter list. A variadic template moves many of those rules into the template's own checking logic. The rules have not disappeared; they have changed location, and that is the weight the designer must carry.
Predicting an Empty Argument List
What do you think happens?
A variadic template is called with no arguments at all. What does its argument list look like, and does the template declaration have to change?
Reveal answer
The argument list is empty, and the template declaration does not have to change.
The source explains that if a variadic template is called with none, the list would be empty, while the template itself is the same. Only the call changes.
Mistakes Beginners Make
Common mistake Assuming the declaration sets how many arguments a call may pass
What it looks likeReading a variadic declaration and expecting it to accept only a fixed count, as a two-parameter template would.
Why it failsThe source says the argument count is set by each call rather than by the declaration.
Do this insteadLook at the declaration for what it allows, then recognize that each call decides the number of arguments.
Common mistake Thinking flexibility means no checking is needed
What it looks likeConcluding that because a variadic template accepts any arguments, every call is automatically valid.
Why it failsChecking the types of the interface can be a possibly elaborate template program, because the checking must cover an open-ended argument list.
Do this insteadTreat the interface check as real template logic that the designer wrote and must maintain.
Common mistake Treating elaborate checking as always present
What it looks likeAssuming every variadic template needs a large amount of checking code.
Why it failsThe source says the checking can be elaborate, not that it always is. Some interfaces are easy to describe.
Do this insteadJudge each interface on its own; some need only a little checking and others need considerably more.
Common mistake Treating the template and the call as one thing, so that a change in argument count seems to require a new template
The Strength and Weakness Are Linked
The strength and the weakness of variadic templates come from the same design choice. The openness that lets a caller pass any arguments is the same openness that forces the template to carry more of the burden of deciding what counts as a valid interface. Understanding them together makes the trade-off clearer than treating them as two separate facts.
Why the Standard Library Relies on Them
The source points out that, because of their flexibility, variadic templates are widely used in the standard library. The reasoning is direct. A library is meant to serve many different callers, and those callers will not all want to pass the same number of arguments. A component that accepts any arguments can be reused in more situations than one that fixes its argument count in advance.
The same connection explains why the cost is worth studying. The components that benefit most from flexibility are exactly the ones whose interfaces must be checked carefully. When you read library-style code, recognize that its generality was bought with template logic the designer had to write.
Key Takeaways
- A variadic template accepts any number of arguments, and each call sets the argument count rather than the declaration.
- The argument list can hold arguments of different types, and one template serves a call with one argument, several arguments, or none.
- Checking the interface of a variadic template can be a possibly elaborate template program, because the checks must cover an open-ended argument list.
- The flexibility and the checking cost come from the same design choice, which is why variadic templates appear so often in the standard library.