How to choose code path for another type in member template function

I have a class that returns a specific device based on runtime.

struct ComponentDc; struct ComponentIc; typedef Device<ComponentDc> DevComponentDc; typedef Device<ComponentIc> DevComponentIc; template<class Component> class Device{ Device<Component>* getDevice() { return this; } void exec() { } }; 

In exec() I would like to print "Hello" if the component type is ComponentDc and world if it is ComponentIc . In addition, these are only two types with which a device can be created.

How to do it?

+4
source share
4 answers

You have two classic possibilities.

First, use two global function overloads, one for ComponentDc , one for ComponentIc :

 void globalExec(ComponentDc) { std::cout << "Hello"; } void globalExec(ComponentIc) { std::cout << "World"; } void Device<Component>::exec() { globalExec(Component); } 

Secondly, use a feature class: a clean template class with no fields and with different typedefs and only static functions as methods. This class has its own specializations for various possible types of arguments.

 template<Component> class DeviceTraits {}; template<> class DeviceTraits<ComponentDc> { static std::string getMessage() { return "Hello"; } }; template<> class DeviceTraits<ComponentIc> { static std::string getMessage() { return "World"; } }; void Device<Component>::exec() { std::cout << DeviceTraits<Component>::getMessage(); } 

The advantage of using feature classes is that you do not need to spoil your global namespace with multiple functions.

The partial specialization of the Device class itself is not always possible, and it is considered more convenient to move any code depending on the template to the feature class.

This is the classic approach used in STL. Alternatively, you can use boost::enable_if or std::enable_if (for the latest compilers).

+4
source

You can explicitly create a template template:

 template<> class Device<ComponentDc> { ... void exec() { cout << "Hello"; } }; 

The same goes for Device<ComponentIc> .

In addition, if you want to limit template parameters to a specific set, you should think about inheritance or composition instead of templates.

+3
source

You can also use boost :: enable_if

http://www.boost.org/doc/libs/1_53_0/libs/utility/enable_if.html http://www.boost.org/doc/libs/1_44_0/libs/type_traits/doc/html/boost_typetraits/reference /is_same.html

 void Device<Component>::exec(boost::enable_if< boost::is_same<Component,ComponentDc> >* enabler = 0) { } void Device<Component>::exec(boost::enable_if< boost::is_same<Component,ComponentIc> >* enabler = 0) { } 
+1
source

Use the specialized template specialization: http://www.cprogramming.com/tutorial/template_specialization.html

Here to use it for a specific method: Template specialization of one method from a template class

0
source

All Articles