Concepts / Fixed-Parameter Templates

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.

  • Programming

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.

Single slotdeclared oncePosition 04 (integer)Position 1alpha (text)Position 2true (boolean)holdsholdsholds
Which positions does a call with three arguments of different types occupy in the single slot the template declares?

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

Definition

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.

Declared listexactly two parametersDeclared listone slot for any argumentsAccepted callsonly two argumentsAccepted callsone, ten, or nonelimitsallows
How does the declared list differ between a fixed-parameter template and a variadic template, and which calls each one accepts?

Same Template, Different Calls

Worked example

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?

  1. 1
    Call with one argument

    The call supplies a single value, so the slot's argument list has a single position.

  2. 2
    Call 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.

  3. 3
    Call with no arguments

    The call supplies nothing, so the argument list is empty. The template is still the same declaration.

  4. 4
    Compare 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.

Result

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.

Call with argumentsany number of themTemplate checkinglogicwritten as template codeInterface checks passmay be elaborateCall usableis checked bydecidesyes
When a call with an open-ended argument list arrives, which part of the system carries the work of deciding whether the interface is valid?

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
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 like

    Reading a variadic declaration and expecting it to accept only a fixed count, as a two-parameter template would.

    Why it fails

    The source says the argument count is set by each call rather than by the declaration.

    Do this instead

    Look 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 like

    Concluding that because a variadic template accepts any arguments, every call is automatically valid.

    Why it fails

    Checking the types of the interface can be a possibly elaborate template program, because the checking must cover an open-ended argument list.

    Do this instead

    Treat 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 like

    Assuming every variadic template needs a large amount of checking code.

    Why it fails

    The source says the checking can be elaborate, not that it always is. Some interfaces are easy to describe.

    Do this instead

    Judge 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.

More concepts starting with F