Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling zero-argument variadic template in C++11

Consider the following artificial example:

template <typename T, typename... Args>
struct A {
  typedef T Type;
};

Using A with 1 or more arguments works while using it with zero arguments fails as expected:

error: wrong number of template arguments (0, should be 1 or more)

Is it possible to make A handle the case of zero template arguments defining A::Type to int if there are no arguments and to the first template argument if there are?

like image 737
vitaut Avatar asked Apr 26 '15 15:04

vitaut


People also ask

What is the use of variadic templates?

With the variadic templates feature, you can define class or function templates that have any number (including zero) of parameters. To achieve this goal, this feature introduces a kind of parameter called parameter pack to represent a list of zero or more parameters for templates.

What is a Variadic template C++?

A variadic template is a class or function template that supports an arbitrary number of arguments. This mechanism is especially useful to C++ library developers: You can apply it to both class templates and function templates, and thereby provide a wide range of type-safe and non-trivial functionality and flexibility.

How to use variadic function in c++?

Variadic functions are functions (e.g. std::printf) which take a variable number of arguments. To declare a variadic function, an ellipsis appears after the list of parameters, e.g. int printf(const char* format...);, which may be preceded by an optional comma.

How do Variadic functions work?

Variadic functions are functions that can take a variable number of arguments. In C programming, a variadic function adds flexibility to the program. It takes one fixed argument and then any number of arguments can be passed.


2 Answers

First define the primary template as the most general case — which also includes zero argument:

template <typename... Args>            //general : 0 or more 
struct A { using Type = int; }

Then partially specialize it for 1 or more parameters as:

template <typename T, typename... Args> //special : 1 or more
struct A<T,Args...>  { using Type = T; }

Once you have this specialization, the primary template would be used for zero-argument only!

Note that mathematically 1 or more is a special case of 0 or more — the latter is a more general case (not the other way round).

like image 163
Nawaz Avatar answered Sep 23 '22 08:09

Nawaz


You could just add a default to the first argument, no specializations necessary:

#include <type_traits>

template <typename T = int, typename... >
struct A {
    using type = T;
};

int main() {
    static_assert(std::is_same<A<>::type, int>::value, "");
    static_assert(std::is_same<A<double, char>::type, double>::value, "");
}
like image 37
Barry Avatar answered Sep 19 '22 08:09

Barry