min 算法通常表示如下:
template <typename T>
const T& min(const T& x, const T& y)
{
return y < x ? y : x;
}
但是,这不允许使用 form 的构造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)
条件运算符会看到一个 xvalue,因此会从转发的对象中移动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);
}