2013-07-11 2 views
0

이 작동하지 않는 추상적 인 템플릿 클래스의 벡터로 만들려면? 알아, 포인터를 써야 해.하지만 이걸 작동 시키려면 또 뭐가 필요하니? 이 작업을 수행하기 위해 기본 구조를 어떻게 바꿀 수 있습니까?방법에 따라

나는 다음과 같은 인터페이스를 사용

// Interface 
    template <typename T> 
    class IRule 
    { 
     public: 
      virtual bool isValid(T value) = 0; 
    }; 

그리고 내 예를 들어 클래스는 다음과 같습니다

class RuleRangeDouble : public IRule<double> 
    { 
     private: 
      double min; 
      double max; 
     public: 

      bool isValid(double value) 
      { 
.... 
      }; 
    }; 
+0

왜 작동하지 않습니다 하나는 특별한 일반을 정의하는 (그러나 템플릿이 아닌) 반환 형식이 getBestValidValue()하는 데 사용되며 (여기에 문제가있는 것 juanchopanza의 대답) isValid(value)에 대한 인수 형식으로 할 수있다? 'RuleRangeDouble'이'IRule'에서 공개적으로 파생되면, 작동하지 않아야 할 이유가 없습니다. –

+0

@JamesKanze 'IRule'이 클래스 템플릿입니다. – juanchopanza

+0

@ juanchopanza 나는 그것을 놓쳤다. 'IRule'이 템플릿 인 경우,'IRule *'은 유효한 타입이 아닙니다. –

답변

1

그것을 virtual 소멸자를 제공하는 것을 잊지 마십시오.

class ValueType 
{ 
    enum { is_int, is_double } my_type; // add more if you want 
    union { my_int; my_double; };  // union only works for simple types 
public: 
    // implicit construction from allowed types 
    ValueType(int x) : my_type(is_int), my_int(x) {} 
    ValueType(double x) : my_type(is_double), my_double(x) {} 
    // use SFINAE for is<type>() function 
    template<typename T> 
    typename std::enable_if<std::is_same<T,int>::value,bool>::type 
    is() const { return my_type==is_int; } 
    template<typename T> 
    typename std::enable_if<std::is_same<T,double>::value,bool>::type 
    is() const { return my_type==is_double; } 
    // implicit type conversion to allowed types 
    // note: does not assert(is<T>()) 
    operator int() { return my_int; } 
    operator double() { return my_double; } 
}; 

class IRule 
{ 
public: 
    virtual bool isValid(ValueType const&) const = 0; // fixed bug in juanchopanza's answer 
    virtual ValueType getBestValidValue() const = 0; // return any type of value 
    virtual ~IRule() {} 
}; 

template<typename T> 
class Rule : public IRule 
{ 
protected: 
    virtual bool valid(T) const = 0; 
    virtual T bestValidValue() const = 0; 
public: 
    bool isValid(ValueType const&value) const 
    { 
    return value.is<T>() 
     && valid(value);   // implicit type conversion to T 
    } 
    ValueType getBestValidValue() const 
    { 
    return bestValidValue();  // implicit construction of ValueType 
    } 
    .... 
} 
+0

덕분에 많은 일을 할 수있는 솔루션을 얻었고 원하는대로했습니다. Visual Studio 2005를 사용해야하고 라이브러리가 그 일부가 아니기 때문에'std :: enable_if' 만 사용할 수 없습니다 ... – prom85

+0

@ prom85 당신은 쉽게 자신의'enable_if'를 정의 할 수 있습니다 :'template struct enable_if {typedef T type; };'and template struct enable_if {};' – Walter

+0

감사합니다. 사실, 완전한''라이브러리에 액세스 할 수 없습니다. – prom85

3

벡터는 예를 std::vector<IRule<double>*>를 들어, 실제의 형태의 벡터가 될 필요가있다. Irule은 유형이 아니며 클래스 템플릿입니다. 템플릿 매개 변수는 인터페이스의 일부가 아닌 경우 그래서 당신은

std::vector<IRule<double>*> vec; 
RuleRangeDouble *rule = new RuleRangeDouble(0, 100); 
vec.push_back(rule); 

을해야합니다, 당신은 일반적인 기본 클래스를 도입 할 수 있습니다.

class IRule 
{ 
    public: 
     virtual bool isValid(T value) = 0; 
     virtual ~IRule() {} 
}; 

template <typename T> 
class Rule : public IRule 
{ 
    ..... 
}; 

class RuleRangeDouble : public Rule<double> 
{ 
    .... 
}; 

그런 다음 원래 사용 사례 샘플이 작동합니다 : 당신은 여러 가지 방법으로 getBestValidValue() 같은 것을 구현할 수

std::vector<IRule*> vec; // IRule really is a type now 
RuleRangeDouble *rule = new RuleRangeDouble(0, 100); 
vec.push_back(rule); 
+0

그건 내 문제 야, 정의되지 않은 유형의 벡터, 포인터 만 ... 내 벡터의 모든 객체에 대해 isValid를 호출하고 싶다. 어떤 유형이든 관계없이 ... 더 많은 클래스가 있기 때문에 RuleRangeDouble 클래스 .. 잘 모르겠다. 아마도 래퍼 솔루션이 존재할 수 있을까? 나는 단지 하나를 생각할 수 없다 ... 그리고 내가 발견 한 사람을 얻을 수 없었다. – prom85

+0

@ prom85 그럼 당신은 공통 기본 클래스 나 변형 타입 (boost :: any' 또는' 부스트 :: 변형'. – juanchopanza

+0

실제로, 나는 당신이 그것을 어떻게 의미하는지 모른다. 기본 클래스는'IRule' 인터페이스 위에 있어야하고 따라서 템플릿이 될 필요가있다. 그리고 불행히도 boost를 사용할 수 없다 ... – prom85

관련 문제