使用模板或宏对多个类型进行静态分派
Static dispatch over multiple types using templates or a macro
我目前正在重构一些代码,我希望SO可以帮助我找出一个聪明的方法,将大量的样板文件减少到几个简单的方法中。我的问题类似于带有模板参数的c++函数分派。
基本上我有几个类(到目前为止有7个),它们都符合相同的模板接口,但不继承任何公共超类,因为不支持虚方法。
假设接口是
template<typename T> class IComponent : public T {
int Food() { return T::Food(); }
bool FooBarred() { return T::FooBarred(); }
};
然后我有两个类符合这个接口
class ComponentA {
int Food() { return 42; }
bool FooBarred() { return false; }
};
class ComponentB {
int Food() { return 5; }
bool FooBarred() { return true; }
};
然后我将这些组件以任意的方式组合在一些组合类中(目前我有12个这样的组合类),它们看起来像这样:
class MultiComponent {
ComponentA cA;
ComponentB cB;
ComponentC cC;
int NumComponents() { return 2; }
int Food(index i) {
if (i == 0)
return cA.Food();
else if (i == 1)
return cB.Food();
else // if (i == 2)
return cC.Food();
}
bool FooBarred(index i) {
if (i == 0)
return cA.FooBarred();
else if (i == 1)
return cB.FooBarred();
else // if (i == 2)
return cC.FooBarred();
}
};
有7个组件类实现了来自接口的9个方法,并由12个不同的包装器组合(到目前为止),这个代码库将会爆炸成几乎什么都没有,只有使用一堆if的动态调度。
我想把它简化成某种聪明的调度程序,比如
template <typename RetVal, typename C>
RetVal ApplyTo(int index, RetVal(*fn)(const C* component)) {
if (index == 0)
return fn(cA);
else if (index == 1)
return fn(cB);
else
return fn(cC);
}
,我可以用它来对第I个组件应用操作符,这样我只需要为每个复合类实现一次ApplyTo,我就可以通过这个方法访问我的组件及其所有的方法和属性。
有可能这样做吗?或者SO有另一个想法,我如何能用模板或可能的宏以更好的方式构建这个。(因为我担心类型系统会妨碍任何模板化的解决方案。)
干杯asg
我已经尝试了一些东西,看看如果这是你想要泛化代码的方式:
#include <iostream>
template<typename T>
class IComponent : public T {
public:
int Food() { return T::Food(); }
bool FooBarred() { return T::FooBarred(); }
};
class ComponentA{
public:
int Food() { return 42; }
bool FooBarred() { return false; }
};
class ComponentB{
public:
int Food() { return 5; }
bool FooBarred() { return true; }
};
class ComponentC{
public:
int Food() { return 6; }
bool FooBarred() { return true; }
};
//An example WRAPPER class
class MultiComponent {
public:
int NumComponents() { return 2; }
template<typename T>
bool foo(IComponent<T>* object)
{
object->Food();
return object->FooBarred();
}
};
//Routes calls to specific instance of components via wrapper object
template <typename RetVal, typename C, typename Wrapper, typename Func>
RetVal ApplyTo(Func func, Wrapper& wrapper )
{
IComponent<C> obj;
return (wrapper.*func)(&obj);
}
//wrapper call backs
typedef bool (MultiComponent::*CallBackC)(IComponent<ComponentC>*);
typedef bool (MultiComponent::*CallBackA)(IComponent<ComponentA>*);
typedef bool (MultiComponent::*CallBackB)(IComponent<ComponentB>*);
int main()
{
MultiComponent wrapper;
//call Component C
CallBackC callback;
callback = &MultiComponent::foo<ComponentC> ;
bool result = ApplyTo<bool, ComponentC, MultiComponent, CallBackC>(callback, wrapper);
std::cout<<"Result of C "<<result<<std::endl;
//call Component A
CallBackA callbackA;
callbackA = &MultiComponent::foo<ComponentA> ;
result = ApplyTo<bool, ComponentA, MultiComponent, CallBackA>(callbackA, wrapper);
std::cout<<"Result of A "<<result<<std::endl;
return 0;
}
相关文章:
- ArduinoJson 6.15.2:JsonObject没有命名类型
- 防止主数据类型C++的隐式转换
- 大量序列中核苷酸类型的快速计数
- 如何从C++中的依赖类型中获得它所依赖的类型
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 是否可以初始化不可复制类型的成员变量(或基类)
- 如何获取std::result_of函数的返回类型
- 从父命名空间重载类型
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- Openssl 1.1.1d无效使用不完整的类型"struct dsa_st"
- 访问者访问变体并返回不同类型时出错
- 在VS2010-VS2015下编译时,如何使用decltype作为较大类型表达式的LHS
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 模板元程序查找相似的连续类型名称
- 是否可以从int转换为enum类类型
- 协变返回类型和分派
- 使用模板或宏对多个类型进行静态分派
- 标记分派结构不能插入对象类型