[英]How Best To Implement A Templated Class with Types That Depend On Each Other
作为一个简化的例子,如果我有类
template <class T, class U> class ProcessEvent
{
public:
ProcessEvent(T* t) : var1(t) { var2 = new U; }
Process() { var2->Process(var1); }
private:
T* var1;
U* var2;
};
class Foo
{
/*data*/
};
class FooProcessor
{
void Process(Foo* foo) {/*functionality*/}
};
class Bar
{
/*data*/
};
class BarProcessor
{
void Process(Bar* bar) {/*functionality*/}
};
所以ProcessEvent类可以有两组不同的模板类型,
ProcessEvent<Foo, FooProcessor>
ProcessEvent<Bar, BarProcessor>
但是,第二个模板类型FooProcessor和BarProcessor直接由第一个模板类型暗示,并且是用户不关心的实现细节。 我的目标是拥有与上面相同的功能,但让ProcessEvent只采用一个模板参数,Foo或Bar。 除了通过ProcessEvent的专业化,这可以做到吗?
我将假设你为了清晰而简化,并且真正使用智能指针或者至少正确地管理内存。
最简单的方法是在第一个类中使用typedef:
class Foo
{
typedef FooProcessor Processor;
// Stuff.
};
然后在你的模板中删除U
并使用typename T::Processor
代替。
你可以这样做:
template<typename T>
class Spec
{
};
template<>
class Spec<Foo>
{
typedef FooProcessor type;
};
template<>
class Spec<Bar>
{
typedef BarProcessor type;
};
然后在需要BarProcessor和FooProcessor时分别使用Spec<T>::type
,T = Bar或T = Foo。
我假设FooProcessor只能处理Foo而BarProcessor只能处理Bar,但其他类型可能有多个处理器类。 因此你可以侵入性地做到:
class FooProcessor
{
public:
typedef Foo value_type;
};
class BarProcessor
{
public:
typedef Bar value_type;
};
你可以使用多态:
template< typename T >
class Processor
{
public:
typedef T value_type;
virtual ~Processor() {}
virtual void process( value_type * ) = 0;
};
class FooProcessor : public Processor<Foo>
{
// implement process
};
您可以使用像Matt Phillips这样的适配器类,但相反,所以它将进程类作为模板参数:
template<typename T>
class Spec
{
};
template<> class Spec<FooProcessor>
{
typedef Foo type;
};
template<> class Spec<Bar>
{
typedef BarProcessor type;
};
通过侵入式键入和Spec适配器键入ProcessEvent模板,将处理器类型作为参数,并使用value_type或type派生另一个。
使用多态性,您的ProcessEvent将把对象类型作为参数(Foo或Bar),并传递一个处理器,该处理器派生自处理器或处理器以处理事件。
如果要处理大量事件并且它总是使用相同的对象处理它们,后一种方法当然会因为通过v表处理而效率稍低。 它部分取决于它们处理的时间以及是否可以内联它的功能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.