Алгоритм 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);
}
int&&
кint
xvalue?! Я думал, что xvalues являются анонимными ссылками rvalue, которые могут быть связаны ссылками rvalue без создания временных? Похоже, то же самое происходит и с вашим исправленным кодом, не так ли? Тип возвращаемого значения —int&&
, а возвращаемое выражение — значение xint
. Почему компилятор больше не предупреждает об этом? - person Johannes Schaub - litb   schedule 24.06.20108.5.3
, это говорит о том, что это создает временное целое при привязке ссылки к xvalue:int x = 0; int &&rx = (int&&)x;
Аналогично при использованииstd::move
. Я думаю, это не может быть намерением. - person Johannes Schaub - litb   schedule 24.06.2010int
не является типом класса. Итак, дляint
создается временный. Я думаю, это дефект. - person Johannes Schaub - litb   schedule 24.06.2010