NiHu  2.0
C++11 techniques in NiHu

Introduction

This document presents the C++11 techniques used in NiHu.

Variadic templates

A new feature of C++11 enables the usage of template classes with variable number of template arguments, a.k.a. variadic templates. Variadic templates are created using the ellipses (...) syntax as demonstrated in the example below. The example also shows function parametrisation and calling using a variadic list of arguments.

template <class...Args>
class VariadicTemplateClass
{
public:
static int a_function(Args...a) {return 0;}
static int b_function(Args...b) {return a_function(b...);}
};

To interpret a code that utilises the variadic syntax you can always think of the ellipses as an extraction of the underlying operation that is the operation applied on the elements of the variadic expression, separated by commas. For example the expression

typename traits<Args>::type...

with Args = bool, char is interpreted as

typename traits<bool>::type, typename traits<char>::type

It is also worth mentoning that the expression template <class...Args> also covers the empty Args case, which means no template parameters in case of the above example class.

What makes variadic templates extremely useful is, of course, specialisation. The basic example defines the disjunction of boolean template parameters as

template <bool...Args>
struct vari_or {
static const bool value = false;
};

As it is seen, the default value is false, which will be utilised in the specialisation. The powerfulness of variadic templates are demonstrated by the specialised classes:

template <bool...Args>
struct vari_or<true, Args...> {
static const bool value = true;
};
template <bool...Args>
struct vari_or<false, Args...> {
static const bool value = vari_or<Args...>::value;
};

As a result, all the specialisations with any number of arguments such as

vari_or<false, true>::value; // 2 args
vari_or<false, true, false, false, true, false>::value; // 6 args
// and so on with any number of args

will work, and give a correct result, which is calculated at compile time. It should be noted that in our example vari_or<false> takes the value from the class vari_or<> (with zero template parameters), and naturally this requires that vari_or<> is a valid and complete class, which

The auto keyword

C++11 allows to use the auto keyword for the definition of variables with explicit initialisation, where the compiler can deduce the type name from the initialisation expression:

auto c = 'a';

This new feature becomes really useful when massively templated codes are used. Consider the following example: Class dirac_wrapper is used to wrap a function space type into a Dirac function space type. Class dirac_wrapper is a template, and dirac_wrapper objects can be constructed from any kind of function space objects, as shown in the following snippet.

template <class FuncSpace>
class dirac_wrapper
{
...
public:
// constructor from function space
dirac_wrapper(FuncSpace const &fs)
{
...
}
};

Now suppose that we have a variable func_space of type func_space_t. The corresponding Dirac wrapper object can be constructed as

dirac_wrapper<func_space_t> dfs(func_space);

This declaration can be made more readable by introducing a factory function template dirac:

// factory function
template <class FuncSpace>
dirac_wrapper<FuncSpace> dirac(FuncSpace const &fs)
{
return dirac_wrapper<FuncSpace>(fs);
}

and initialising our new variable with the factory function's return value:

auto dfs = dirac(func_space);

note that the compiler deduced the template parameter of the factory function from its argument, and the return type defined the type of the explicit initialiser of the variable definition. The result is a simple Matlab-like readable expression that compiles to the same as the old-fashioned explicit constructor call.

The type_traits library

lambda expressions

NiHu::dirac
const dirac_field< Field > & dirac(field_base< Field > const &f)
dirac field view factory
Definition: field.hpp:629