以下不起作用:
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)
{
....
};
};
答案 0 :(得分: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);
答案 1 :(得分: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
}
....
}