具有自定义范围 [0, 64] 的 C++ 数据类型?

问题描述

我寻找了类似的问题,但没有找到答案。

基本上,我需要声明/定义一个特定范围从 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;
}