Std :: clamp - detects that the value of the returned function is bound to const T &

It is better not to bind the return value of std::clamp to const ref if one of its parameters min or max is the value of r.

Typical implementation of std::clamp (very simplified):

 template <class T> constexpr const T& clamp(const T& value, const T& min, const T& max) { return value < min ? min : max < value ? max : value; } 

And as mentioned in the cppreference for std :: clamp , a dangerous situation arises when someone writes:

 int n = -1; const int& r = std::clamp(n, 0, 255); // r is dangling 

Is there any way to collect data at compile time?

+6
source share
1 answer

If you want to write your own clip function, you can discover it and do something with it.

For example, suppose you want the clamp function to return by value if this is the only way to ensure that we don't get a broken link:

 #include <type_traits> template<class A, class B, class C> constexpr std::conditional_t< std::is_lvalue_reference<A &&>::value && std::is_lvalue_reference<B &&>::value && std::is_lvalue_reference<C &&>::value, std::add_lvalue_reference_t<std::common_type_t<A, B, C>>, std::common_type_t<A, B, C> > clamp(A && value, B && min, C && max) { return value < min ? min : max < value ? max : value; } 

This would make clamp(n, 0, 255) effectively have the signature int clamp(int&, int&&, int&&) ; you will only get int & clamp(int&, int&, int&) if all 3 inputs are lvalue references. Creating the returned const link is trivial if you want it.

You can also not compile the function if they are not all lvalue references:

 #include <type_traits> template<class A, class B, class C> constexpr std::add_lvalue_reference_t<std::common_type_t<A, B, C>> clamp(A && value, B && min, C && max) { static_assert(std::is_lvalue_reference<A &&>::value && std::is_lvalue_reference<B &&>::value && std::is_lvalue_reference<C &&>::value, ""); return value < min ? min : max < value ? max : value; } 
+1
source

Source: https://habr.com/ru/post/1014447/


All Articles