我尝试做的是这个简单的模板钳功能。
我想在运行时和编译时确保upper >= lower
。
template <typename T>
T clamp(const T& lower, const T& upper, const T& n)
{
weak_assert(upper >= lower);
return std::max(lower, std::min(n, upper));
}
写一下似乎是合理的:
static_assert(upper >= lower, "invalid bounds");
但是,当使用非constexpr
参数调用时,编译器会给我这个:
Static_assert expression is not an integral constant expression
In instantiation of function template specialization 'clamp<int>' requested here
有没有办法正确实现这一目标?使用constexpr
调用时(例如,clamp<int>(0, 10, myvar)
应该触发static_assert,否则通常的动态断言会发生?
答案 0 :(得分:6)
从C ++开始14 constexpr函数中允许assert()
,但即使使用C ++ 11,您也可以使用operator ,
来欺骗它:
#include <cassert>
template <typename T>
constexpr T clamp(const T& lower, const T& upper, const T& n)
{
return assert(upper >= lower), std::max(lower, std::min(n, upper));
}
答案 1 :(得分:1)
编译器在这里禁止static_assert
是正确的,因为在c ++中你不能在constexpr上下文中使用函数参数......但要做更多或更少的你想要的东西,你可以在{{ 1}}并推导出它们的价值,就像你可以推断它们的类型一样。它可以完成,例如像这样:
std::integral_constant