我认为有多种方法可以解决这个问题。据我所知,n
只能取特定范围内的数字。为此,您可以防止构造函数被运行:
template <typename T, T Min, T Max>
class ranged_type_c
{
public:
typedef T value_type;
ranged_type_c(const value_type& pX) :
mX(pX)
{
check_value();
}
const value_type& get(void) const
{
return mX;
}
operator const value_type&(void) const
{
return get();
}
private:
void check_value(void)
{
if (mX < Min || mX > Max)
throw std::range_error("ranged value out of range");
}
value_type mX;
};
这个想法可以再详细阐述一下,但是基本思路已经清晰。现在您可以夹紧范围:
struct foo_c
{
foo_c(ranged_value_c<int, 0, 100> i) :
x(i)
{}
int x;
};
如果传递的值不在0-100的范围内,上述代码会抛出异常。
在运行时,我认为你最初的想法是最好的:
template <typename T>
const T& check_range(const T& pX, const T& pMin, const T& pMax)
{
if (pX < pMin || pX > pMax)
throw std::range_error("ranged value out of range");
return pValue;
}
struct foo
{
foo(int i) :
x(check_range(i, 0, 100))
{}
int x;
}
就是这样。与上面相同,但 0 和 100 可以替换为调用某个返回有效最小值和最大值的函数。
如果您最终使用函数调用来获取有效范围(建议这样做,以保持最小限度的混乱和更高的组织性),我建议添加一个重载:
template <typename T>
const T& check_range(const T& pX, const std::pair<T, T>& pRange)
{
return check_range(pX, pRange.first, pRange.second);
}
为了允许像这样的东西:
std::pair<int, int> get_range(void)
{
return std::make_pair(0, 100);
}
struct foo
{
foo(int i) :
x(check_range(i, get_range()))
{}
int x;
}
如果我要选择,即使范围是编译时,我也会选择运行时方法。即使没有进行高度优化,编译器将生成相同的代码,而且与类版本相比,它更加简洁易读。请保留HTML标签。
T0
如何通知失败?例如,是否有像bool bad()
这样的函数? - GManNickG