一种常见的技术是拥有一个类模板,其中模板参数仅充当唯一标记(“标签”)以使其成为唯一类型:
template <typename Tag>
class Fruit {
int p;
public:
Fruit(int p) : p(p) { }
int price() const { return p; }
};
using Apple = Fruit<struct AppleTag>;
using Banana = Fruit<struct BananaTag>;
请注意,标签类甚至不需要定义,就足够了declare唯一的类型名称。这是有效的,因为标签实际上是used模板中的任何位置。并且您可以声明类型名称inside模板参数列表(向@Xeo 致敬)。
The using
语法为 C++11。如果您无法使用 C++03,请改为这样写:
typedef Fruit<struct AppleTag> Apple;
如果通用功能占用大量代码,那么不幸的是,这会在最终的可执行文件中引入大量重复代码。可以通过使用实现该功能的公共基类,然后从它派生一个专门化(您实际实例化)来防止这种情况。
不幸的是,这需要您重新实现所有不可继承的成员(构造函数、赋值……),这本身就会增加一点开销——所以这只对大型类有意义。这里应用到上面的例子:
// Actual `Fruit` class remains unchanged, except for template declaration
template <typename Tag, typename = Tag>
class Fruit { /* unchanged */ };
template <typename T>
class Fruit<T, T> : public Fruit<T, void> {
public:
// Should work but doesn’t on my compiler:
//using Fruit<T, void>::Fruit;
Fruit(int p) : Fruit<T, void>(p) { }
};
using Apple = Fruit<struct AppleTag>;
using Banana = Fruit<struct BananaTag>;