C++11虚拟模板方法或转发可变模板
C++11 Virtual template method or Forwarding variadic template
我有这样的类:
template<class C>
class OperatorsMap
{
typedef void (C::*voidFunctionType)(void);
private:
std::map<long, voidFunctionType> m;
public:
template<typename T>
void Insert(long id, T f1)
m.insert(std::make_pair(id,(voidFunctionType)f1));
template<typename O, typename... Args>
bool SearchAndCall(long id, O *obj, Args&&... args)
{
auto mapIter = m.find(id);
if(mapIter == m.end()) return false;
auto mapVal = mapIter->second;
auto Fun = (bool(C::*)(Args ...))(mapVal);
return (obj->*Fun)(std::forward<Args>(args)...);
}
};
class IConditionBase
{
public:
virtual ConditionInfo GetInfo() = 0;
virtual void ClearOperators() = 0;
};
template<class C>
class ConditionBase : public IConditionBase
{
public:
template<typename O>
ConditionBase(O object){mObject = object;}
~ConditionBase(){}
ConditionInfo GetInfo(){return mInfo;}
template<typename F>
void AddOperator(long id, const char* name, F fun)
{
mInfo.AddOperatorInfo(name, id);
mOperators.Insert(id, fun);
}
template<typename... Args>
bool CallOperator(long id, Args&&... args)
{
return mOperators.SearchAndCall(id, mObject, std::forward<Args>(args)...);
}
private:
ConditionInfo mInfo;
OperatorsMap<C> mOperators;
C* mObject;
class ModuleConditionService
{
public:
ModuleConditionService();
~ModuleConditionService();
template<typename... Args>
bool EvaluateCondition(long conditionID, long operatorID, Args&&... args)
{
bool ret = false;
IConditionBase* cnd = GetCondition(conditionID);
switch(conditionID)
{
case ID_ACTUAL_TRIP_ID: (static_cast<cndActualTripID>(cnd))->CallOperator(operatorID, std::forward<Args>(args)...);
default: cout << "Condition with ID " << conditionID << " not found!";
}
return ret;
}
private:
void AddCondition(IConditionBase* condition);
IConditionBase *GetCondition(long conditionID);
vector<IConditionBase*> mConditionContainer;
};
class cndActualTripID : public ConditionBase<cndActualTripID>
{
public:
cndActualTripID();
~cndActualTripID();
using ConditionBase<cndActualTripID>::ConditionBase;
bool operator_Equal(long id);
bool operator_Greater(long id);
bool operator_IN(unsigned int idsCount, long ids[]);
};
在ModuleConditionService
的构造函数中,我创建这样的条件:
AddCondition(new cndActualTripID());
然后我主要调用EvaluateCondition:
ModuleConditionService* service = new ModuleConditionService();
long arr[] = {111,122,125,0,129};
bool ret1 = service->EvaluateCondition(1, 10, 5, arr);
bool ret2 = service->EvaluateCondition(1, 9, 89);
bool ret3 = service->EvaluateCondition(1, 8, 122);
一切都很好,但我认为EvaluateCondition
的功能不太好。现在只有一个条件cndActualTripID
,但当有100个条件时,类型转换(static_cast<cndActualTripID>(cnd))->CallOperator(operatorID, std::forward<Args>(args)...);
将非常令人困惑,并且在.h文件中类型转换我认为不是一个好主意。当函数CallOperator
将像virtual
一样位于IConditionBase
中时,这会有所帮助,但它是模板函数:(我必须将args
从EvaluateCondition
的参数中获取到OperatorsMap
中的SearchAndCall
中,但我不知道如何获取。请你帮助我或有其他想法,如何基于ID
为类cndActualTripID
(和其他)调用CallOperator
(ID
是继承的属性,具有每个ConditionBase
)。我使用c++11。这只是代码的重要部分,如果缺少什么,请告诉我,我会发布它。
非常感谢。
我将程序重新设计为write n.m。没有可变参数,只有一个固定的(向量)。现在我有了ConditionBaseOperators类,我在其中存储和调用函数。它比以前更好(更安全)吗?谢谢
template<class C>
class MODULECONDITIONDOMAIN_API ConditionBaseOperators : public ConditionBase
{
typedef bool (C::*Operators)(vector<string>);
public:
template<typename O>
ConditionBaseOperators(O obj){mObject = obj;}
~ConditionBaseOperators(){}
void AddOperator(long id, string name, Operators function)
{
AddOperatorInfo(id, name.data());
mOperators.insert(make_pair(id, function));
}
bool CallOperator(long id, vector<string> args)
{
bool ret = false;
auto it = mOperators.find(id);
if(it != mOperators.end())
{
auto fun = (bool(C::*)(vector<string>))(it->second);
ret = (mObject->*fun)(args);
}
else
EERROR("Operator with ID %d not found in module %s", id, GetInfo().GetName().c_str());
return ret;
}
private:
map<long,Operators> mOperators;
C* mObject;
};
class MODULECONDITIONDOMAIN_API ConditionBase : public Wertyz::DomainLayer::Core::DomainObject
{
public:
ConditionBase(){}
~ConditionBase(){}
ConditionInfo GetInfo();
void SetInfo(ConditionInfo info);
void SetInfo(long id, string name);
void AddOperatorInfo(long id, const char* name);
virtual bool CallOperator(long id, vector<string> args) = 0;
long VtoL(vector<string> vec, unsigned int idx);
unsigned long VtoUL(vector<string> vec, unsigned int idx);
double VtoD(vector<string> vec, unsigned int idx);
int VtoI(vector<string> vec, unsigned int idx);
long long VtoLL(vector<string> vec, unsigned int idx);
vector<long> VtoVL(vector<string> vec);
private:
ConditionInfo mInfo;
};
class SERVICECORE_API ModuleConditionService
{
public:
ModuleConditionService();
~ModuleConditionService();
bool EvaluateCondition(long conditionID, long operatorID, vector<string> args);
private:
void AddCondition(ConditionBase *condition);
void AddAction(ActionBase* action);
ActionBase *GetAction(long idx);
ConditionBase *GetCondition(long conditionID);
vector<ConditionBase*> mConditionContainer;
vector<ActionBase*> mActionContainer;
};
class MODULECONDITIONDOMAIN_API cndActualTripID : public ConditionBaseOperators<cndActualTripID>
{
public:
cndActualTripID();
~cndActualTripID();
using ConditionBaseOperators<cndActualTripID>::ConditionBaseOperators;
private:
bool operator_Equal(vector<string> args);
bool operator_Greater(vector<string> args);
bool operator_IN(vector<string> args);
long GetValue();
};
ModuleCondition.cpp
bool ModuleConditionService::EvaluateCondition(long conditionID, long operatorID, vector<string> args)
{
return GetCondition(conditionID)->CallOperator(operatorID, args);
}
cndActualTripID.cpp
cndActualTripID::cndActualTripID() : ConditionBaseOperators<cndActualTripID>::ConditionBaseOperators(this)
{
SetInfo(ID_ACTUAL_TRIP_ID, "ActualTripID");
AddOperator(1, "Greater", &cndActualTripID::operator_Greater);
AddOperator(2, "Equal", &cndActualTripID::operator_Equal);
AddOperator(3, "IN", &cndActualTripID::operator_IN);
}
相关文章:
- 虚拟决赛作为安全
- PowerPC ppc64le上的Gcc Woverloaded虚拟错误
- 如何在C++中获得"静态纯虚拟"功能?
- C++无法定义虚拟函数 OUTER 类和头文件
- 正在折叠转发引用
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 在模板基类中为继承类中的可选重写生成虚拟方法
- 尝试将unique_ptrs推送到向量时使用纯虚拟函数错误
- 有没有比在库中添加一个并非由所有派生类实现的新虚拟函数更好的设计实践
- 大小虚拟继承中的派生类
- 链接器找不到在虚拟类 c++ 中访问的静态字段的符号
- 使用 C++ 和 i2c 工具从虚拟 i2c 写入和读取
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- 如果整个应用程序是虚拟映射的,为什么 new 会进行系统调用?
- 跨 DLL 边界访问虚拟方法是否安全/可能?
- std::is_trivially_copyable_v 关于虚拟功能
- 删除C++继承中虚拟类成员的代码重复
- 子类地址等于虚拟基类地址?
- 当覆盖存在时调用基本虚拟"binded to object"函数
- C++11虚拟模板方法或转发可变模板