std :: зажим — определить, связано ли возвращаемое значение функции с const T & amp;

Лучше не связывать std::clamp вернуть значение const ref, если один из его min или же max параметры являются значениями.

Типичная реализация std::clamp (очень упрощенно):

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

И как уже говорилось в cppreference для std :: зажим Существует опасная ситуация, когда кто-то пишет:

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

Есть ли способ обнаружить эти случаи во время компиляции?

6

Решение

Если вы хотите написать свою собственную функцию зажима, вы можете обнаружить это и что-то с этим сделать.

Например, предположим, что вы хотите, чтобы функция зажима возвращалась по значению, если это единственный способ гарантировать, что мы не получим висячую ссылку:

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

Это сделало бы clamp(n, 0, 255) эффективно иметь подпись int clamp(int&, int&&, int&&); вы только получите int & clamp(int&, int&, int&) если все 3 входа являются ссылками lvalue. Оформление возвращенной ссылки const тривиально, если вы так желаете.

Вы также можете сделать так, чтобы функция не компилировалась, если бы не все ссылки на lvalue:

#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

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]