2016-07-18 4 views
0

전달 나는이 수업을 :C++ 11 가상 템플릿 방법 또는 가변 인자 템플릿

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 파일로 형 변환 될 것이라고 생각하지 않습니다. 기능 CallOperatorvirtual 같은 IConditionBase에있을 것입니다 때, 도움이 될,하지만 템플릿 기능입니다 :(내가 OperatorsMap에서 SearchAndCallEvaluateCondition의 인수로부터 args을 받아야하지만. 당신이 나를 도와 또는 일부를 가질 수 있습니다하십시오 방법을 모른다 다른 아이디어, (및 기타) ID (ID 모든 상속 된 속성은 ConditionBase있는) 기반으로 전화하는 방법. 나는 C++ 11 함께 작동합니다. 그것은 코드의 중요한 부분입니다, 누락 된 경우 제발 무엇을 말하면 내가 무엇을 게시하는지 알려주세요.

+4

, 그래서 당연히이 여기의 "가상 템플릿 방법"입니다합니다. '.h 파일에 캐스팅하는 것이 좋지 않습니다.'뭐라고 생각하니? 왜 그렇게 생각하니? CRTP를 사용한 적이있는 모든 사람에게 알리십시오. 인라인 메서드에서의 캐스팅은 동일한 파일에 있는지 여부에 관계없이 라인 외부 정의에서 캐스팅하는 것보다 효과적입니다. 어쩌면 질문을 더 줄이거 나, 더 많은 것을 추가하기보다는 집중하는 것이 좋습니다. –

+0

위험한 일을하려고합니다. EvaluateCondition은 하나이지만 SearchAndCall이 훨씬 더 나쁩니다. 유형 안전성은 전혀 없습니다. 디자인을 다시 생각해보십시오. –

+0

귀하의 궁금한 점이 있으면 SearchAndCall을 버리고 검색을 포함시킬 수 있습니다. 지도 사용자가 전화를하도록하십시오. 검색은 템플릿 일 필요는 없습니다. 또한지도 자체가 템플릿 일 필요는 없습니다. 멤버 함수에 대한 일반적인 포인터를 저장합니다. 어쨌든 실제 유형으로 캐스팅합니다 (위험하다고 생각하면 권장하지 않습니다). –

답변

0

내 프로그램을 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); 
} 
관련 문제