の転送、私はこのクラスがあります:ModuleConditionService
のコンストラクタでC++ 11の仮想テンプレートメソッドまたは可変長引数テンプレート
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[]);
};
私はこのような条件を作成します。
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);
すべて機能は正常ですが、機能はです3210はかなり良いとは思いません。今度はただ一つの条件cndActualTripID
がありますが、条件が100になると、そのタイプのキャスト(static_cast<cndActualTripID>(cnd))->CallOperator(operatorID, std::forward<Args>(args)...);
は非常に混乱し、.hファイルの型キャストは良くないと思います。機能CallOperator
がvirtual
ようIConditionBase
になりますときには、役立つだろうが、それはテンプレート関数である:(私はOperatorsMap
でSearchAndCall
へEvaluateCondition
の引数からargs
を取得する必要がありますが、私はあなたが私を助けたり、いくつかを持つことができますかわかりません他のアイデア、クラスcndActualTripID
(と他の)ID
(ID
はすべてConditionBase
を持つ継承属性です)に基づいて呼び出す方法。私はC++ 11で働いています。何を投稿すればいいですか?
ありがとうたくさんありがとう
なものが存在しない可能性があるため、当然のようにそこここには、 "仮想テンプレート方法は" ありません、と。 '.hファイルの型キャストは良いとは思いません。' What?なぜそう思うの?これまでにCRTPを使用したことのある人にそのことを伝えてください。インラインメソッドでのキャストは、同じファイル内であろうとなかろうと、アウトオブラインでのキャストよりも有効ではありません。たぶんあなたは質問をもっと細かくして、それを集中させることができます。 –
危険なことをしようとしています。 EvaluateConditionは1ですが、SearchAndCallは非常に悪いです。どんな型の安全性もありません。デザインの再考を検討してください。 –
あなたの直ぐ質問では、SearchAndCallを捨てて、検索だけを含めることができます。マップユーザーに呼び出しをさせてください。検索はテンプレートである必要はありません。さらに、マップそのものはテンプレートである必要はありません。メンバ関数への汎用ポインタを格納するだけです。とにかくあなたの実際のタイプにキャストします(危険で、あなたが私に尋ねるならばお勧めしません)。 –