C++98的老码农们,应该都知道std::max() 函数可以从两个数中求最大值。
但其实从C++11开始,std::max()可以用来从多个数中求最大值,前提是需要搭配初始化列表。
int m = std::max({1, 2, 3, 4, 5});
注意小括号里面的大括号。这个是C++11的初始化列表。
怎么样,一次性比较多个数字,简洁不少吧。但唯一的限制是类型要一样,即使有符号的int和无符号的int放一起,也不能用std::max()。
unsigned int a = 1; int b = 2; int c = 3; // 编译报错 int m1 = std::max({a, b, c}); // 编译报错 int m2 = std::max<int>({a, b, c}); // 编译成功 int m3 = std::max({(int)a, b, c});
有网友问能不能不用{}直接用max()放入多个参数来直接比较大小呢?是C++做不到吗?
当然不是。C++肯定能做到,尤其是C++11之后,引入了可变参数模板这一特性。虽然官方没有实现。我来实现一把:
#include <iostream> namespace guodong { template<class T> T max(T head) { return head; } template<class T, typename... Args> T max(T head, Args... args) { T t = max<T>(args...); return (head > t)?head:t; } } // end of namespace int main() { int m = guodong::max(1, 2, 3); std::cout<<m<<std::endl; return 0; }
这种可变参数模板的函数,递归展开的时候需要一个作为『终止条件』的函数。也就是上面单参的 T max(T head)。
要注意终止函数一定要在同名的可变参模板的函数之前定义,不然编译不过。
好了,再回答一下网友的问题,我想之所以C++11没有这样实现max,估计是防止max()传入过多的参数吧。一是模板实例化的时候会爆炸。二是一个函数,参数个数如果太多,其实也会影响函数调用的性能。而使用{}借助初始化列表这么一中转,max的参数个数就可以控制在一个(初始化列表作为一个参数传入max)。