Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

static_assert on reference template argument type

What I'm trying to do is this simple template clamp function. I want to ensure upper >= lower either in runtime and at compile-time.

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));
}

It seems reasonable to write:

static_assert(upper >= lower, "invalid bounds");

However, when called with non-constexpr arguments, compiler gives me this:

Static_assert expression is not an integral constant expression
In instantiation of function template specialization 'clamp<int>' requested here

Is there any way to achieve this properly? When called with constexpr (say, clamp<int>(0, 10, myvar) the static_assert should be fired, otherwise the usual dynamic assert will do?

like image 206
Hedin Avatar asked Mar 11 '23 00:03

Hedin


1 Answers

Starting with C++14 assert() is allowed in constexpr functions, but even with C++11 you can trick it in by using 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));
}
like image 188
kamikaze Avatar answered Mar 12 '23 15:03

kamikaze