如果参数在编译时已知,我可以执行可选的static_assert吗?

时间:2016-04-29 11:23:19

标签: c++ assert

我有一个只接受大于0的无符号整数的函数,并且有一个调试断言来检查它:

void foo(unsigned int x) {
    assert(x > 0);
}

是否可以在此处添加static_assert,以便代码仍然可以编译并接受非编译时常量的参数?

foo(0); // compilation error
foo(1); // fine
foo(get_x_from_user()); // fine

我知道我可以将x设为模板参数,但我更希望保持这种调用方式:foo(5);而不是foo<5>();

我在想可能有一种方法可以通过自定义整数类型来解决这个问题,但是我无法在这条路线上走得太远。有没有办法做到这一点?

2 个答案:

答案 0 :(得分:1)

据我所知,如果不引入某种模板,这是不可能的,例如:

template<int T>
class CustomInt
{
public:
    static constexpr int value = T;
};

template<int val>
void check(CustomInt<val> /*k*/)
{
    static_assert(CustomInt<val>::value > 0, "error!");
    check(val);
}

void check(int k)
{
    std::cout << "check";
}

int s()
{
    volatile int x = 5;
    return x;
}

int main() {
    check(CustomInt<0>());
    check(s());
    return 0;
}

这只是将模板移动到自定义类型。

答案 1 :(得分:1)

如果坚持foo(12),你就无法做到。因为您希望编译器在编译时知道函数参数的值。并且它不可能,在运行时评估参数值。然后它不能constexpr,然后您就无法在static_assert中使用它。