static_assert参考模板参数类型

时间:2017-01-28 11:10:52

标签: c++ c++11 templates

我尝试做的是这个简单的模板钳功能。 我想在运行时和编译时确保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,否则通常的动态断言会发生?

2 个答案:

答案 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

[live demo]