5

我有一个基于运行时返回特定设备的类。

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()中,如果组件类型是,我想打印“Hello”,如果是,我想打印ComponentDcworld ComponentIc。此外,这些是唯一可以用来创建设备的两种类型。

我该怎么做呢 ?

4

4 回答 4

4

你有两种经典的可能性。

首先,使用两个全局函数重载,一个 for ComponentDc,一个 for 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(); 
}

使用特征类的好处是你不必用几个函数破坏你的全局命名空间。

关于Device类本身的部分特化——这并不总是可能的,将任何模板参数特定的代码移动到特征类中被认为更方便。

这是 STL 中使用的经典方法。或者,您可以使用boost::enable_ifor std::enable_if(对于最新的编译器)。

于 2013-03-19T08:29:55.107 回答
3

您可以显式实例化模板:

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

也是如此Device<ComponentIc>

此外,如果您想将模板参数限制为特定的集合,您应该考虑继承或组合而不是模板。

于 2013-03-19T08:29:17.707 回答
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)
{
}
于 2013-03-19T08:37:04.630 回答
0

用于实例模板专业化:http ://www.cprogramming.com/tutorial/template_specialization.html

此处将其用于特定方法: Template specialization of a single method from a templated class

于 2013-03-19T08:28:10.447 回答