Алгоритм min обычно выражается так:
template <typename T>
const T& min(const T& x, const T& y)
{
return y < x ? y : x;
}
Однако это не допускает конструкции вида min(a, b) = 0
.Вы можете добиться этого с помощью дополнительной перегрузки:
template <typename T>
T& min(T& x, T& y)
{
return y < x ? y : x;
}
Я хотел бы объединить эти две перегрузки с помощью идеальной пересылки:
template <typename T>
T&& min(T&& x, T&& y)
{
return y < x ? std::forward<T>(y) : std::forward<T>(x);
}
Однако g ++ 4.5.0 выплевываетпредупреждение для min(2, 4)
, что я возвращаю ссылку на временный.Я сделал что-то не так?
Хорошо, я понял.Проблема с условным оператором.В моем первом решении, если я вызову min(2, 4)
, условный оператор видит значение x и, таким образом, перемещается из перенаправленного x
, чтобы создать временный объект.Конечно, было бы опасно возвращать это по ссылке!Если я перешлю целое выражение вместо x
и y
отдельно, компилятор больше не будет жаловаться:
template <typename T>
T&& min(T&& x, T&& y)
{
return std::forward<T>(y < x ? y : x);
}
Хорошо, я избавился от ссылок на арифметические типы:)
#include <type_traits>
template <typename T>
typename std::enable_if<std::is_arithmetic<T>::value, T>::type
min(T x, T y)
{
return y < x ? y : x;
}
template <typename T>
typename std::enable_if<!std::is_arithmetic<T>::value, T&&>::type
min(T&& x, T&& y)
{
return std::forward<T>(y < x ? y : x);
}