写作时
T min(T& a,T& b)
{return a<b?a:b;}
并致电min(3,4)
,会产生错误。
如何实现通用min?
答案 0 :(得分:12)
那是因为非const
左值引用(T&
)无法绑定到右值(3
和4
是右值,这直观地表示它们没有对象身份)。
尝试使用const
的左值引用,可以绑定到rvalues(毕竟,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)
}
这是live example。
<强>更新强>
上述解决方案只允许将相同类型的值传递给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以来可用)来确定要用作返回类型的正确类型。
再一次,这是一个live example。
答案 1 :(得分:1)
你必须使用模板标题
template<typename T>
T const& min(T const & a, T const & b)
{
return a<b?a:b;
}
你可以用类似的方式达到最大值:
template<typename T>
T const& max (T const &a, T const& b)
{
return a<b? b:a;
}
您必须确保T类型支持&lt;操作