Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ templates: Select different type based on value of template parameter

Tags:

How do I accomplish the following in C++, and what is doing such things called?

template <bool S>
class NuclearPowerplantControllerFactoryProviderFactory {
  // if S == true
  typedef int data_t;
  // if S == false
  typedef unsigned int data_t;
};
like image 269
porgarmingduod Avatar asked Nov 23 '11 13:11

porgarmingduod


People also ask

How will you restrict the template for a specific datatype?

There are ways to restrict the types you can use inside a template you write by using specific typedefs inside your template. This will ensure that the compilation of the template specialisation for a type that does not include that particular typedef will fail, so you can selectively support/not support certain types.

Can we pass Nontype parameters to templates?

Template non-type arguments in C++It is also possible to use non-type arguments (basic/derived data types) i.e., in addition to the type argument T, it can also use other arguments such as strings, function names, constant expressions, and built-in data types.

Can a template be a template parameter?

A template argument for a template template parameter is the name of a class template. When the compiler tries to find a template to match the template template argument, it only considers primary class templates. (A primary template is the template that is being specialized.)

Which template can have multiple parameters?

C++ Class Template with multiple parameters You can also use multiple parameters in your class template.


1 Answers

By specialization:

template <bool> class Foo;

template <> class Foo<true>
{
  typedef int data_t;
};

template <> class Foo<false>
{
  typedef unsigned int data_t;
};

You can choose to make one of the two cases the primary template and the other one the specialization, but I prefer this more symmetric version, given that bool can only have two values.


If this is the first time you see this, you might also like to think about partial specialization:

template <typename T> struct remove_pointer     { typedef T type; };
template <typename U> struct remove_pointer<U*> { typedef U type; };


As @Nawaz says, the easiest way is probably to #include <type_traits> and say:

typedef typename std::conditional<S, int, unsigned int>::type data_t;
like image 171
Kerrek SB Avatar answered Sep 19 '22 17:09

Kerrek SB