c++ - 最小和完美转发

标签 c++ templates c++11 forwarding rvalue-reference

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),条件运算符会看到一个 xvalue,因此会从转发的 x 移动以生成一个临时对象。当然,通过引用返回它是危险的!如果我转发整个表达式而不是单独转发 xy,编译器就不会再提示了:

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

最佳答案

在我看来,您似乎在试图过分简化问题。不幸的是,让它完全正确绝对不是一件容易的事。如果你还没有读过 N2199 ,现在是这样做的好时机。右值引用不断发展,因此它的 min 和 max 引用实现可能不再完全正确,但它至少应该是一个相当不错的起点。警告:引用实现比您想要的要复杂很多!

关于c++ - 最小和完美转发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3095549/

相关文章:

c++ - 从 C 字符串构造 boost::type_erasure::any 但存储为 std::string

c++ - 如何修复此错误 'no matching function for call' ?

c++ - CMake 为 C 文件禁用 -std=c++11 标志

c++ - 对每个簇大小具有上限要求的聚类算法

c++ - 按位将 uint32_t 强制转换为 C/C++ 中的 float

C# - 无法访问 C++/CLI .dll 中包含的方法

php - 将文本字符串附加到 WooCommerce 产品标题

c++ - 为什么 C++ 不能推断模板类型?

java - 通过 JNI 的数据未正确传递

c++ - 匿名命名空间中模板化类的友元