我有一个基于运行时返回特定设备的类。
struct ComponentDc;
struct ComponentIc;
typedef Device<ComponentDc> DevComponentDc;
typedef Device<ComponentIc> DevComponentIc;
template<class Component>
class Device{
Device<Component>* getDevice() { return this; }
void exec() { }
};
在exec()
中,如果组件类型为ComponentDc
,我想打印“Hello”,如果是ComponentIc
,则打印世界。此外,这些是唯一可以创建设备的两种类型。
我该怎么做?
答案 0 :(得分:4)
你有两种经典的可能性。
首先,使用两个全局函数重载,一个用于ComponentDc
,一个用于ComponentIc
:
void globalExec(ComponentDc) { std::cout << "Hello"; }
void globalExec(ComponentIc) { std::cout << "World"; }
void Device<Component>::exec() { globalExec(Component); }
其次,使用traits-class:纯模板类,没有字段,具有不同的typedef,只有静态函数作为方法。该类对不同的可能参数类型有自己的特化。
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();
}
使用traits类的优点是您不必使用多个函数破坏全局命名空间。
关于部分地专门化Device
类本身 - 它并不总是可行的,并且将任何特定于模板参数的代码移动到traits类中被认为更方便。
这是STL中使用的经典方法。或者,您可以使用boost::enable_if
或std::enable_if
(针对最新的编译器)。
答案 1 :(得分:3)
您可以明确地实例化模板:
template<> class Device<ComponentDc> {
...
void exec() { cout << "Hello"; }
};
Device<ComponentIc>
同样如此。
此外,如果要将模板参数限制为特定集,则应考虑继承或组合而不是模板。
答案 2 :(得分:1)
您也可以使用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)
{
}
答案 3 :(得分:0)