Quick Tip: C++ Variadic Templates

Newer standards of C++ (starting with C++11) let us enhance templates with variable-length lists of types. We can create simpler method declarations with less copy-pasting.

Simple example

We all know how to sum multiple numbers, huh? A possible approach:

The most interesting part is typename... Ts in the template definition. It says the compiler that Ts is a parameter pack (a list of types). In this function, we take the first argument and sum it with that of the rest. The only thing to remember is that operator+ must be defined for all the types we used as an argument.

It’s just templates

You may think: “Hey, it’s just a recursion!”. It’s not. All those methods are generated at compile time and will be different ones in the sense of memory address etc. Also, it’s not possible to modify this variadic template function to receive e.g. vector contents. Vector allocates memory for contents in runtime after all the methods are generated. For parameter packs, the number of elements has to be known during compilation.

Look at the example of moving average (of last three items) below:

The output would be:

Example 2: moving average
AVG(4, 16, 78) = 32.6667
AVG(16, 78, 0) = 31.3333
AVG(78, 0, 15) = 31
AVG(0, 15, -300) = -95
AVG(15, -300, 680) = 131.667

This approach won’t work for less than 3 elements, because there is no required template and compiler would not know what method to generate.

Size of

You can easily count contents of a parameter pack using sizeof...(ts). With parameter packs, it just says how many elements are there; you will get no information about memory size, etc.

Output is:

Example 3: Output
Message 1 (3 more messages)
Message 2 (2 more messages)
Message 3 (1 more messages)
Message 4

This one was pretty straightforward, I think.

Simple logger

That’s enough to make use of variadic templates. As an example, here’s a simple function working as a logger – it prepends message with current time. The declaration is the same as for printf (I copied it from the reference in the beginning):

Sample output:

[Sun Mar 05 14:27:29 2017] Example 4: Simple logger
[Sun Mar 05 14:27:29 2017] Test message 1
[Sun Mar 05 14:27:29 2017] Multiple elements 10, 152.398
[Sun Mar 05 14:27:29 2017] IO Error: Could not load file hello_variadic.txt

Further reading

Variadic templates work nicely with std::tuple and STL containers. There are also new features coming in C++17 like fold expressions. But that’s the topic for another article. You can find more here:

2 thoughts on “Quick Tip: C++ Variadic Templates

  1. > All those methods are >generated at runtime Name is a bit misleading, it has nothing to do with memory as it would be usually.

    I disagree. Using `sizeof` to get the *size of* variadic pack seems perfectly natural. It may be a tad misleading because of it’s semantics when applied to types/values, but that has nothing to do with the name.

    • The first one is obviously compile-time, thanks for pointing it out.

      With sizeof, I meant that usually you expect it to give a memory size of an object, e.g. of struct of char[3], integer, long long, including padding. sizeof…(args) just says how many params are there and I find it a bit confusing in context of previous, also available usage. I will rephrase it today to focus on this difference.

Leave a Reply

Your email address will not be published. Required fields are marked *