Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 编译时错误如何限制整数的允许范围?_C++ - Fatal编程技术网

C++ 编译时错误如何限制整数的允许范围?

C++ 编译时错误如何限制整数的允许范围?,c++,C++,我想创建一个整数值类型,但范围有限。 尝试使用超出允许范围的值创建此类型的实例将导致编译时错误 我发现了一些示例,它们允许在出现错误时触发编译时错误,但没有一个示例允许有限范围的整数(没有名称) 这是可能的吗?< P>你所要的是艾达的特性,而不是C++。我不相信您可以在编译时限制整数的范围。可以通过组合宏和C++0x的静态断言来做类似的事情 #define SET_CHECK(a,b) { static_assert(b>3 && b<7); a=b; } #def

我想创建一个整数值类型,但范围有限。 尝试使用超出允许范围的值创建此类型的实例将导致编译时错误

我发现了一些示例,它们允许在出现错误时触发编译时错误,但没有一个示例允许有限范围的整数(没有名称)


这是可能的吗?

< P>你所要的是艾达的特性,而不是C++。我不相信您可以在编译时限制整数的范围。

可以通过组合宏和C++0x的静态断言来做类似的事情

#define SET_CHECK(a,b) { static_assert(b>3 && b<7); a=b; }
#define SET_CHECK(a,b){static_assert(b>3&&b是的,但它很笨重:

// Defining as template but the main class can have the range hard-coded
template <int Min, int Max>
class limited_int {
private:
    limited_int(int i) : value_(i) {}
    int value_; 
public:
    template <int Val> // This needs to be a template for compile time errors
    static limited_int make_limited() { 
        static_assert(Val >= Min && Val <= Max, "Bad! Bad value.");
        // If you don't have static_assert upgrade your compiler or use:
        //typedef char assert_in_range[Val >= Min && Val <= Max];
        return Val;
    }

    int value() const { return value_; }
};

typedef limited_int<0, 9> digit;
int main(int argc, const char**) 
{

    // Error can't create directly (ctor is private)
    //digit d0 = 5; 

    // OK
    digit d1 = digit::make_limited<5>(); 

    // Compilation error, out of range (can't create zero sized array)
    //digit d2 = digit::make_limited<10>(); 

    // Error, can't determine at compile time if argc is in range
    //digit d3 = digit::make_limited<argc>(); 
}
//定义为模板,但主类可以硬编码范围
模板
类别有限公司{
私人:
有限整数(整数i):值(i){}
int值;
公众:
模板//这需要是编译时错误的模板
静态受限\u int make\u limited(){

static_assert(Val>=Min&&Val运行时整数的值只能在运行时检查,因为它只在运行时存在,但如果对所有写入方法进行运行时检查,则可以保证其内容。您可以使用给定的限制构建一个常规的整数替换类

对于常量整数,您可以使用模板强制执行这样的操作

template<bool cond, typename truetype> struct enable_if {
};
template<typename truetype> struct enable_if<true, truetype> {
    typedef truetype type;
};
class RestrictedInt {
    int value;
    RestrictedInt(int N)
        : value(N) {
    }
public:
    template<int N> static typename enable_if< (N > lowerbound) && (N < upperbound), RestrictedInt>::type Create() {
        return RestrictedInt(N);
    }
};
模板结构启用\u如果{
};
模板结构启用\u如果{
typedef-truetype类型;
};
阶级限制{
int值;
限制性(内部N)
:数值(N){
}
公众:
模板静态typename启用_如果<(N>下限)和&(N<上限),限制为>::type Create(){
返回限制t(N);
}
};

尝试使用不在范围内的模板值创建此类将导致替换失败和编译时错误。当然,仍然需要使用运算符等修饰以替换int,如果您希望编译时保证其他操作,则必须为它们提供静态函数(有更简单的方法来保证编译时算法)。

正如您所注意到的,已经有一种形式的枚举诊断

它通常是粗糙的:即检查是“松散的”,但也可以提供一种粗糙的检查形式

enum Range { Min = 0, Max = 31 };
您通常可以在定义的最小值和最大值之间分配任何值(毫无疑问)


事实上,您通常可以分配多一点(我认为gcc可以使用2的幂)。

Boost对数字关系有一个静态断言:@in silico:请尝试并发布指向新版Boost的链接(截至编写时为1.44):)我认为在编译时,当从一个大的数字类型分配到一个小的数字类型时,Clang已经有了某种类型的诊断。我想gcc/visual也会有。这就足够了,还是您想要一个分隔良好的范围?@Matthieu M:我在寻找0-100或1-50这样的范围。在这种情况下,您必须使用类似于@Motti建议:)对于大小为0或1的数组,这是一个不错的主意。我使用了常规的enable\u if技术。这非常好-为了防止编译器对\u范围变量中未使用的assert\u发出警告,我添加了“={}”对于这一行。@DeadMG,这是一种传统的方法,我曾经使用
enable\u if
来保持模板的冷静,但后来意识到它的杀伤力太大了(
static\u assert
是语言中一个受欢迎的补充)@Andrew,实际上最好只使用typedef(我在写答案时很懒)我会更新我的答案。这太可怕了:/当情况确实不需要定义宏时,请不要定义宏,使用模板函数会更好。