4

当我写

T min(T& a,T& b)
{return a<b?a:b;}

并调用min(3,4),它会产生错误。

如何实现通用最小值?

4

2 回答 2

12

这是因为非const左值引用 ( T&) 不能绑定到右值(3并且4是右值,这直观地意味着它们没有对象标识)。

尝试使用左值引用来const代替,它可以绑定到右值(毕竟,min()函数不应该改变其参数的状态)。

template<typename T>此外,如果您正在编写函数模板,请不要忘记该部分:

template<typename T> // <== Don't forget this, if you are writing a template
T min(T const& a, T const& b)
//      ^^^^^       ^^^^^
{
    return (a < b) ? a : b;
}

例如,考虑这个小程序:

#include <iostream>

template<typename T> // <== Don't forget this, if you are writing a template
T min(T const& a, T const& b)
//      ^^^^^       ^^^^^
{
    return (a < b) ? a : b;
}

int main()
{
    int x = 42;
    int y = 1729;

    std::cout << min(x, y) << std::endl; // Passing lvalues, that would be OK also
                                         // with your original code.

    std::cout << min(42, 1729) << std::endl; // Passing rvalues, this would not be OK
                                             // with your original code (non-const
                                             // lvalue references cannot bind to rvalues)
}

这是一个活生生的例子


更新:

上述方案只允许将相同类型的值传递给min(),否则编译器将无法进行类型推导(如果第一个和第二个参数的类型不同,应该T是什么?):

min(3.14, 42); // Huh? What is `T` here, `double` or `int`?

要强制编译器对 使用特定类型T,您可以显式指定模板参数:

min<double>(3.14, 42);

然而,这不是一个非常优雅的选择(用户每次都必须手动输入正确的模板参数)。相反,您可以让您的函数模板接受两个模板类型参数,而不是一个:

#include <type_traits>

template<typename T, typename U>
typename std::common_type<T, U>::type min(T const& a, U const& b)
{
    return (a < b) ? a : b;
}

并使用std::common_type<>类型特征(自 C++11 起可用)来确定用作返回类型的正确类型。

再一次,这里是一个活生生的例子

于 2013-04-14T14:43:08.430 回答
1

你必须使用模板头

template<typename T>
T const& min(T const & a, T const & b)
{
   return a<b?a:b;
}

你可以用类似的方式为 max 做到这一点:

template<typename T>
T const& max (T const &a,  T const& b)
{
  return a<b? b:a;
}

您必须确保类型 T 支持 < 运算符

于 2013-04-14T14:42:58.193 回答