Working with Variable Numbers of Arguments
A variadic template is a template that can accept an arbitrary number of arguments of arbitrary types.
Why Fixed Inputs Run Out
Most of the templates you have met so far are written with a fixed picture of what they will receive. You decide ahead of time how many inputs there are and what kind each one is, and the template is built around that shape. This works well when the job has a predictable form, but many useful tasks do not.
Consider a logging helper. Sometimes it is handed a message with no extra values, sometimes a message with one value, and sometimes a dozen values of different kinds. A template that only handles a set number of inputs would force you to write several near-identical versions, or to give up on the flexibility altogether.
What do you think happens?
How many arguments might a logging helper need to accept in a single call?
Reveal answer
Zero, one, or many
The helper's inputs vary from call to call. A message may come with no extra values, one value, or many values of different kinds, so a design that fixes the count and kinds would need several near-identical versions.
The idea behind this section is that a single template can be written so that it does not commit to a particular number of inputs or to particular kinds of inputs. That capability is what the course calls a variadic template. Each part of that name points to a question you can ask about any template: how many arguments does it take, and what kinds of arguments may appear in the call?
Tracing a Call Against a Fixed Template
Before looking at variadic templates, trace what happens with a template that has a fixed input list. A fixed input list has a set number of slots, and each slot has a set kind. Every call must fill exactly those slots.
A fixed two-slot template receiving a third argument
A template is designed with two slots: the first slot takes a name as text, and the second slot takes a count as a whole number. A caller supplies three arguments: a name, a count, and an extra note.
- 1Count the slots
The design has exactly two slots. It does not have a place for a third value.
- 2Match the arguments to slots
The name fills the first slot and the count fills the second slot. The extra note has no slot to go into.
- 3Check the fit
Because every call must fill exactly those slots, this call does not fit the design. The template was built around a shape that the call does not have.
A fixed template cannot accept the extra note without being rewritten or wrapped in another design.
What an Arbitrary Count Means
A variadic template is a template that can accept an arbitrary number of arguments of arbitrary types.
An arbitrary count includes zero, one, or many arguments. There is no minimum or fixed size. A variadic template does not have a fixed number of slots. Instead, it is written to take whatever arguments the call supplies, in any quantity, within what its design can handle.
What do you think happens?
Can a variadic template be called with no arguments at all?
Reveal answer
Yes, because zero is included in an arbitrary count
An arbitrary count includes zero, so there is no minimum size. A variadic template is not required to receive at least one argument.
What Arbitrary Types Means
The second half of the definition concerns kinds of arguments. Arbitrary types means the arguments in a call need not share a single type. One call might pass a whole number, a piece of text, and a decimal number, and all three can belong to the same variadic template call.
Fixed Slots Versus Open Input Lists
The clearest way to separate the two designs is to compare the shape of the input list. The table below sets the two side by side, and the diagram after it shows the same contrast visually.
| Feature | Fixed-argument template | Variadic template |
|---|---|---|
| Number of inputs | A set number of slots | Arbitrary, including zero |
| Kind of each input | Each slot has a set kind | Arbitrary types, need not share one type |
| Fit to a call | Every call must fill exactly the slots | Takes whatever the call supplies, within its design |
| Best suited to | Predictable, fixed shapes | Inputs that genuinely vary from call to call |
Fixed-argument and variadic templates compared by their input lists
When you are deciding between the two, ask whether the number or kinds of inputs are truly open-ended. If a function or template always takes the same set of inputs, a fixed design is simpler to read and to reason about. The variadic form earns its place when the inputs genuinely vary from call to call.
Following One Mixed Call
Now trace a single call with three arguments of different kinds. The template's input list is not fixed to any one of these kinds, so the call is allowed to carry all three. Each argument keeps its own kind and its own place in the call.
Notice what the diagram shows and what it does not. The three arguments differ in kind, and the call carries them together. The source describes what the template is designed to accept. It does not describe how the template internally stores or processes each argument, so the position labels above are a way to read the call, not a claim about any particular implementation.
Mistakes Beginners Make with Variadic Designs
Common mistake Assuming a variadic template must receive at least one argument
What it looks likeWriting a call with no arguments and expecting an error
Why it failsAn arbitrary count includes zero, so there is no minimum size.
Do this insteadTreat zero, one, and many arguments as all valid calls, as long as the design handles them.
Common mistake Assuming all arguments must share one type
What it looks likeBelieving a call that mixes a whole number and text is invalid
Why it failsArbitrary types means the arguments need not share a single type.
Do this insteadMixed-kind calls are the normal case the design is built for.
Common mistake Confusing acceptance with handling
What it looks likeConcluding that a template does the same useful thing with every kind of argument because it accepts them all
Why it failsAcceptance describes what the template is designed to take. What it does with each argument depends on its design.
Do this insteadCheck what the template does with each kind of argument, not only what it accepts.
Common mistake Using a variadic design when the inputs are always the same
What it looks likeMaking a template open-ended for a job that always takes the same two values
Why it failsIf the inputs never vary, the open-ended design adds complexity without benefit.
Do this insteadUse a fixed design when the shape is predictable, and reserve the variadic form for inputs that genuinely vary.
Choosing a Design for a Task
A task always takes exactly three inputs: a user identifier, a date, and a status code. Would a fixed-argument template or a variadic template fit this task better, and why?
Hints
- Ask whether the number of inputs is open-ended or fixed.
- Ask whether the kinds of inputs are predictable for every call.
A logging helper receives a message, and sometimes a varying number of extra values of mixed kinds. Explain which design the source suggests and what the design must still decide for each argument.
Hints
- Compare this task with the always-three-inputs task above.
- Remember that acceptance and handling are separate questions.
Key Takeaways
- A variadic template is a template that can accept an arbitrary number of arguments of arbitrary types.
- An arbitrary count includes zero, one, or many arguments, so there is no minimum or fixed size.
- Arbitrary types means the arguments in one call need not share a single type.
- A fixed-argument template has a set number of slots, each with a set kind, and every call must fill exactly those slots.
- Acceptance describes what a template is designed to take; what it does with each argument still depends on its design.