我有一个看起来像这样的函数:
int div_round_up(int x, int y) {
/**
* This function only works for positive divisor and non-negative dividend!!
*/
assert(y > 0 && x >= 0);
if (x == 0)
return 0;
return (x - 1) / y + 1;
}
它不能与y <= 0
或x < 0
一起使用。这对我来说没关系,我甚至可以动态检查正确的值,但我想静态检查,当有人提供错误的值时。如果我将x和y定义为无符号,它们将从负值静默转换为巨大的正值,这会产生错误的结果,所以我不想要那样。当有人试图像div_round_up(variable, -7)
那样尝试提供负值时,我想让编译失败。我该怎么办?
答案 0 :(得分:3)
要在编译时验证一个数字(这是static_assert
的作用),必须在编译时知道它。要了解为什么需要这样做,请考虑div_round_up(read_integer_from_file(), read_keyboard_character())
之类的内容。这样做的明显缺点是你必须在编译时知道数字。
最简单的方法是使它们成为模板参数,这样就可以让函数的实现(几乎)保持不变:
template<int x, int y>
int div_round_up() {
static_assert(y > 0 && x >= 0, "This function only works for positive divisor and non-negative dividend");
if (x == 0)
return 0;
return (x - 1) / y + 1;
}
可以将其称为div_round_up<3, 4>()
和will fail the compilation when the static_assert
fires。
答案 1 :(得分:2)
如果您正在使用gcc或clang,则可以包含宏
#define div_round_up(a, b) (__builtin_constant_p(b) ? drus(a, b) : drud(a, b))
和两个不同的函数,其中drus
包含b的静态断言,而drud
则不包含。{/ p>
答案 2 :(得分:0)
你可以用一些魔法做到这一点(一位非法的俄罗斯代码大师告诉我这个技巧)
#define check2(x) typedef char checkVal[(x)?1:-1];
int main() {
check2(3<4);
check2(5<4);
return 0;
}
但在这种情况下还有一个限制。编译器应该知道该值的结果。在任何其他情况下它都是不可能的(恕我直言)。