1

以下不起作用:

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

现在如何制作不同规则的向量?我知道,我必须使用指针......但是我还需要做什么才能让它工作?我怎样才能改变我的基本结构来完成这项工作?

我使用如下接口:

// 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)
            {
....
            };
    };
4

2 回答 2

3

向量必须是实际类型的向量,例如std::vector<IRule<double>*>. Irule它本身不是一个类型,它是一个类模板。所以你需要

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

如果模板参数不是接口的一部分,可以引入一个通用的基类。不要忘记给它一个virtual析构函数:

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

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

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

然后您的原始用例示例将起作用:

std::vector<IRule*> vec; // IRule really is a type now
RuleRangeDouble *rule = new RuleRangeDouble(0, 100);
vec.push_back(rule);
于 2013-07-11T08:03:54.087 回答
2

您可以通过多种方式实现类似的东西getBestValidValue()。一种是定义一个特殊的通用(但非模板)返回类型,getBestValidValue()也可以作为参数类型isValid(value)(juanchopanza 的答案在这里是错误的):

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
  }
  ....
}
于 2013-07-11T10:17:23.900 回答