问题描述
我寻找了类似的问题,但没有找到答案。
基本上,我需要声明/定义一个特定范围从 0 到包括 64 的变量。 我使用枚举吗?一个结构?我可以在声明变量时这样做吗? 我想在结构中使用它。
当然我可以写一些 if/else 检查,但是必须有一种更简单的方法而不需要创建数组[64]。
解决方法
如果你只需要一个受约束的整数,你可以在构造函数中检查范围。像这样:
#include <stdexcept>
template<int max>
class ConstrInt {
public:
ConstrInt(int val) {
if (val > max)
throw std::out_of_range("");
m_val = val;
}
int value() const {
return m_val;
}
private:
int m_val;
};
int main(){
ConstrInt<64> a{1};
auto aa = a.value();
ConstrInt<64> b{65}; // exception for > 64
}
,
我是否使用枚举?
我不知道它会有什么用处。
结构?
如果要定义自定义数据类型,那么要定义一个类(结构就是类)。
我可以在声明变量时这样做吗?
如果这就是您的意思,您可以定义自定义数据类型的变量。
当然我可以写一些 if/else 检查,但是必须有一种更简单的方法而不需要创建数组[64]。
没有必要为了检查一个值是否在一个范围内而创建一个数组。这是一个示例检查:
if (x >= 0 && x <= 64)
,
您可以定义一个带有 unsigned char
的类,并使其像内置的无符号整数类型一样环绕,这样 0 - 1
结果为 64
并且 {{1 }} 结果为 64 + 1
。
示例:
0
示例:
template<unsigned End = 64>
class usmall {
public:
// implicit conversion constructor,making sure the value is in the range [0,End]
usmall(unsigned char v = 0) : data(v % (End + 1)) {}
// implicit user defined conversion operator
operator unsigned char () const { return data; }
// pre increment and decrement operators
usmall& operator++() { if(data==End) data = 0; else ++data; return *this; }
usmall& operator--() { if(data==0) data = End; else --data; return *this; }
// post increment and decrement operators
usmall operator++(int) { usmall rv(*this); ++*this; return rv; }
usmall operator--(int) { usmall rv(*this); --*this; return rv; }
// common arithmetic operators
usmall& operator+=(const usmall& rhs) {
data = (data + rhs.data) % (End + 1);
return *this;
}
usmall& operator-=(const usmall& rhs) {
if(data < rhs.data) data += (End + 1);
data -= rhs.data;
return *this;
}
usmall& operator*=(const usmall& rhs) {
data = (data * rhs.data) % (End + 1);
return *this;
}
usmall& operator/=(const usmall& rhs) {
data /= rhs.data;
return *this;
}
private:
unsigned char data;
};
// free arithmetic functions
template<unsigned End>
auto operator+(const usmall<End>& lhs,const usmall<End>& rhs) {
usmall rv(lhs);
rv += rhs;
return rv;
}
template<unsigned End>
auto operator-(const usmall<End>& lhs,const usmall<End>& rhs) {
usmall rv(lhs);
rv -= rhs;
return rv;
}
template<unsigned End>
auto operator*(const usmall<End>& lhs,const usmall<End>& rhs) {
usmall rv(lhs);
rv *= rhs;
return rv;
}
template<unsigned End>
auto operator/(const usmall<End>& lhs,const usmall<End>& rhs) {
usmall rv(lhs);
rv /= rhs;
return rv;
}