The clamp functions are badly designed
--
Hello ! I’m Xavier Jouvenot and today, we are going to see why the std::clamp
and std::ranges::clamp
functions of the C++ standard are badly designed and how we can simply improve it.
Self promotion: Here are a few social networks where you can follow me and check my work as a programmer and a writer 😉 Personal blog, Twitter, GitHub
The issue with std::clamp and std::ranges::clamp
Since C++17, the function std::clamp is available as a helper to keep a variable in a range of value defined by 2 variables specified during the function call. In C++20, the function std::ranges::clamp was also added to the C++ standard.
Those function are defined as such:
namespace std
{
template<class T>
constexpr const T& clamp( const T& v, const T& lo, const T& hi );template<class T, class Compare>
constexpr const T& clamp( const T& v, const T& lo, const T& hi, Compare comp );namespace ranges
{
template< class T, class Proj = std::identity, std::indirect_strict_weak_order<std::projected<const T*, Proj>> Comp = ranges::less >
constexpr const T&
clamp( const T& v, const T& lo, const T& hi, Comp comp = {}, Proj proj = {} );
} // namespace ranges
} // namespace std
And code using those function can look like that:
auto value = std::clamp (variable, 0, 100);
auto other_value = std::ranges::clamp (other_variable, -100, 0);
But it also can look like the following code:
auto value = std::clamp (50, 100, 75);
And in that case, it is very difficult to guess what the intent of the developer writing this line of code is. Indeed, min and max of the range can be reversed because of a mistake in the code, which is, according to the C++ standard, an undefined behavior. Or the developer writing this line thought that the clamp
function was taking the range before the value to be clamped.
Whatever the origin of the reason, this code doesn’t generate any warning during the compilation, when we could easily imagine a solution to make this kind of error not go unnoticed.
Improvements possible
In order to make the developer’s life easier, one solution could be to change the design of the clamp
function: coupling the 2 parameters related to the range of the clamp
…