我想写一些字符串包装器,如果它对其类型有效,它们将接受一个字符串:
Length
有效字符串:mm、m、ft、inAngle
有效字符串:度、弧度
我想像这样的用途:
Length len = read_from_keyboard(); // or some means of initialization
if( len.is_valid() ) { ... }
所以我写了这些实现。
struct Length
{
QString m;
Length() {}
Length( QString s ) { if( is_valid_string(s) ) { m = s; } }
QString operator() () { return m; }
bool is_valid() { return is_valid_string(m); }
static bool is_valid_string( QString s ) {
return s == "mm" || s=="m" || s=="ft" || s=="in";
}
};
和
struct Angle{
QString m;
Angle() {}
Angle( QString s ) { if( is_valid_string(s) ) { m = s; } }
QString operator() () { return m; }
bool is_valid() { return is_valid_string(m); }
static bool is_valid_string( QString s ) {
return s == "deg" || s=="rad";
}
};
在我看来,这似乎是某种形式的静态多态性,is_valid_string()
这是它们在实现上的唯一区别。
由于我有很多这样的类,我想到了使用静态继承(而不是通过虚拟)来掌握通用功能。
所以,我想到了使用奇怪的重复模板模式:
template <class T>
struct ConstrainedText {
QString m;
ConstrainedText() {}
ConstrainedText( QString s ) { if( T::is_valid_string(s) ) { m = s; } }
QString operator() () { return m; }
bool is_valid() { return T::is_valid_string(m); }
};
struct Angle : public ConstrainedText<Angle> {
static bool is_valid_string( QString s ) {
return s == "deg" || s="rad";
}
};
struct Length : public ConstrainedText<Angle> {
static bool is_valid_string( QString s ) {
return s == "mm" || s="m" || s=="ft" || s=="in";
}
};
但现在我失去了基类中的隐式构造函数,我必须重写它们!
有没有其他方法可以实现它以便拥有相同的接口 [default constructor
和]implicit constructor
并且is_value()
只为不同的部分(静态)编写最少的代码is_valid_string()
?
我知道我可以使用预处理器,但我希望代码对调试器友好。