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); }
Second, use traits-class: pure template class with no fields and with different typedefs and only static functions as methods. This class has own specializations for different possible argument types.
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 traits classes is that you don't have to spoil your global namespace with several functions.
About partially specializing the Device
class itself - it is not always possible, and it is considered more convenient to move any template-argument-specific code into traits class.
This is the classic approach used in STL. Alternatively, you can use boost::enable_if
or std::enable_if
(for the latest compilers).