如何最好地实现具有相互依赖类型的模板类
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),并传递一个从processor或processor派生的处理器来处理事件。
如果有大量的事件要处理,并且总是用同一个对象来处理,那么后一种方法当然会稍微效率低一些,因为它是通过v表来处理的。这在一定程度上取决于它们需要多长时间来处理,以及执行处理的函数是否可以内联。
- 如何从C++中的依赖类型中获得它所依赖的类型
- 将依赖名称显式标记为类型名和模板的奇怪之处
- 当基类是依赖类型时,这是一个缺陷吗
- 通过依赖类型使用非类型模板参数的单类型模板参数类模板的部分专用化
- 使用 'typename' 关键字将非类型视为依赖上下文中的类型
- 为什么依赖模板类型在部分专用化中不可推导?
- 为什么即使直到最后才定义实际类型,也可以将依赖名称视为完整
- 为什么不需要在 C++20 中的依赖类型之前指定"typename"?
- 如何使用类型专用化模板方法,该类型本身就是一个模板,其中只有返回类型依赖于模板类型
- 类型依赖于可变参数模板的类
- 类型依赖模板名称
- 模板类型依赖和继承
- C++中的循环类型依赖项死锁
- c++ 中带有容器迭代器的循环类型依赖关系(GCC 失败,而 MSVC 正常)
- C++使变量类型依赖于用户输入
- 使返回类型依赖于调用源
- 如何专用化基于类型依赖类型的C++模板化类函数
- 将 POD 联合双关到基本类型:依赖于实现或符合标准
- 使用类型依赖模板名的声明
- 非类型模板参数,其类型依赖于另一个参数