C++11 New Feature: Variadic Template

Home / C++11 New Feature: Variadic Template

C++11 New Feature: Variadic Template

December 5, 2015 | Article | 1 Comment

Before the possibilities of the new C++ language standard, C++11, the use of templates was quite limited when it campe to implementing for instance function objects (functors) & tuple facilities. Implementing these sort of things using earlier C++ standard often require similar codes to be repeated various times without forgetting preprocessor metaprogramming. However, using variadic templates, new features of C++11, make programming using templates easier, cleaner, & more memory-efficient.

In this article we will discuss about Variadic Template on C++11. I assume that you have understood what class & function templates are and how to declare, define, and use them.

What is Variadic Template?

Variadic template is a template, which can take an arbitrary number of template arguments of any type. Both the classes & funcitons can be variadic. Example can be seen below:

template<typename... Arguments>
class VariadicTemplate;

Any of the following ways to create an instance of this class template is valid:

VariadicTemplate<double, float> instance;
class VariadicTemplate;
VariadicTemplate<bool, unsigned short int, long> instance;
VariadicTemplate<char, std::vector<int>, std::string, std::string, std::vector<long long>> instance;

The number of variadic template arguments can also be zero, which mean that following also valid

VariadicTemplate<> instance;

However, a template like this:

template<typename T, typename... Argument>
class VariadicTemplate;

Must be supplied by at least one type as a template argument (which is for typename T), unless default type has been initialized, like in in the following declaration:

template<typename T = int, typename... Argument>
class VariadicTemplate;

Ellipsis Operator

Ellipsis operator (…) is an operator used in different context in C++. It;s name comes from an ellipsis mechanism in C. In this mechanism programmer can create a funciton taking variable number of parameters. Probably the most famous function in both C & C++ to take advantace of this mechanism is printf and scanf function from C standard library.

printf(const char* format, ...);
scanf(const char* format, ...);

Ellipsis mechanism can also be used with preprocessor in a form of a macro. A macro take a variable number of parameters is called a variadic macro.

#define VARIADIC_MACRO(...)

In C++, the ellipsis operator got a new meaning in different context called exception handling. The operator is used in catch blocks after try blocks which can be seen as following:

try {
   // try block
} catch (...) {
   // catch block
}

Which “catch” any exception thrown by try block and then executes the code on catch block. Thus any exception regardless of types will be taken as if parameter of function.

Later on C++11, variadic templates has brought yet another meaning for this operator. The operator works somewhat like in ellipsis mechanism with more complex. As seen at this snippet:

template<typename... Arguments>
void SampleFunction(Arguments... parameters);

The content of the variadic template arguments are called parameter packs. These packs will then be unpacked inside of function parameters. For example:  If we create a function call to previous variadic template

SampleFunction<int, int>(16,24);

then an equivalent template would be:

template<typename T, typename U>
void SampleFunction(T param1, U param2);

“Sizeof…” Operator

Another operator used with variadic templates is the sizeof… operator (yes it is sizeof followed by three dot). Unlike sizeof operator which can determine the size of a type such as sizeof(int) or sizeof(double), sizeof… operator can be used to determine the amount of types given into a variadic template. A snippet below will demonstrate:

template<typename... Arguments>
class VariadicTemplate {
  static const unsigned short int size = sizeof...(Arguments);
}
void SampleFunction(T param1, U param2);

Two Ellipsis together? (……)

In some circumtances, there can be two ellipsis operators put together (……) and yes there are six dot there which also can be separated (written as … …) Probably the most clear way, however, is to separate those two operators witha comma (such as …,…) is still acceptable.

This kind of syntax can appear with variadic function templates using ellipsis mechanism:

template<typename... Arguments>
void SampleFunction(Arguments..., ...);

Inheritance and Initialization List

When it comes to classes, variadic templates can be used with inheritance & initialization lists. Inheritance taking advantage of variadic templates can be accomplished like this:

template<typename... BaseClasses>
class VariadicTemplate : public BaseClasses...

And if we want to create a constructor inside this class using initialization list to call the constructor of all the given base classes as template arguments, we would have to do it this way:

template<typename... BaseClasses>
class VariadicTemplate : public BaseClasses... {
  VariadicTemplate(BaseClasses&&... base_classes) : BaseClasses(base_classes)... {

  }
};

Variadic Class Template Specialization

Like class templates, variadic class templates can also be specialized. With template, the specialization happens like this:

template<typename T>
class Template {
public:
  void SampleFunction(T param) {

  }
};
template<>
class Template<int> {
public:
  void SampleFunction(int param) {

  }
};

But with variadic templates it become like this:

template<typename... Arguments>
  class VariadicTemplate {
public:
  void SampleFunction(Arguments... param) {

  }
};

template<>
  class VariadicTemplate<double, int, long> {
public:
  void SampleFunction(double param1, int param2, long param3) {

  }
};

Conclusion

Templates have been a powerful feature in C++. Now, after the introduction of variadic template, templates have proven themselves even more powerful. Variadic templates are a trusworthy solution to implement delegates and tuples. And, instead of C-style ellipsis mechanism, variadic templates can offer a typesafer solution to replace them.

, ,

About Author

about author

xathrya

A man who is obsessed to low level technology.

1 Comment
  1. Implementation of Delegates in C++11 - Xathrya.ID

    […] In C++, it would be useful to be able to bind an object with its member function and produce a global function. Such features exists in other languages, for example C#. In C++, there are member function pointers but they do not provide the feature we talk about. In this article we will discuss about a simple implementation of delegates in C++ using member function pointers and C++11 using variadic templates. […]

Leave a Reply

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

Social media & sharing icons powered by UltimatelySocial