Modern C++ In-Depth — Variadic Templates and Parameter Packs

Phani Adusumilli
FactSet
Published in
5 min readJul 19, 2022

--

In our previous installment, we looked at forwarding references and how they can be used to transparently pass arguments from one function call to another. This week, we’ll use that as a springboard to examine variadic templates and parameter packs.

Motivation

Last time, we introduced the example below to demonstrate how one might write a make_unique<T> utility function:

namespace fds {
template <typename T, typename A>
std::unique_ptr<T> make_unique(A&& a)
{
return std::unique_ptr<T>(new T(std::forward<A>(a)));
}
template <typename T, typename A, typename B>
std::unique_ptr<T> make_unique(A&& a, B&& b)
{
return std::unique_ptr<T>(new T(std::forward<A>(a), std::forward<B>(b)));
}
}

While this implementation is perfectly adequate when constructing a std::unique_ptr<T> for a type that takes up to two arguments, it will not work if T requires, say, five arguments. One way to address this issue would be to manually add even more overloads. But, is there a better way?

Variadic Templates and Parameter Packs

What if we could tell the compiler that it should expect to receive zero or more parameters (regardless of type), and that it should just pass all of those parameters to the constructor of our encapsulated type, T?

With the introduction of C++11, we can do exactly that by using a variadic template.

--

--

Phani Adusumilli
FactSet
Writer for

I’m an architect who is passionate about distributed systems, APIs, Data Lakes, and Data Mesh in Financial Services