简洁实现min(),返回最小值的多个值

时间:2016-01-25 10:30:06

标签: c++ c++14 variadic-templates min template-meta-programming

使用std::min(),我们可以std::min(a, b)。但是,如果我想要min(a, b, c)min(a, b, c, d, e)怎么办?我知道以下实现有效:

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

template <typename T, typename... Ts>
const T& min(const T& x, const T& y, const Ts&... xs) {
  return min(min(x, y), xs...);
}

但是我想要一个简洁的功能(前提是它当然可以)。我试过以下

using std::swap;
template <typename T, typename... Ts>
const T& min(const T& x, const T& y, const Ts&... xs) {
  return min(min(x, y), xs...);
}

这不适用于min(1, 2, 3)。如果我只能导入std::swap()的特定重载,这个问题就可以解决,遗憾的是,在当前的C ++中,这似乎是不可能的。所以,我问,是否有一个简洁的实现只用一个函数就可以达到我想要的效果?请注意,我正在考虑使用C ++ 14。请不要C ++ 1z。

2 个答案:

答案 0 :(得分:3)

我会咬人:

#include <initializer_list>
#include <algorithm>
#include <functional>

template<template<typename> class CompT = std::less, typename T, typename... Ts>
T const& variadic_min(T const& a, T const& b, Ts const&... ts) {
    return std::min({ std::cref(a), std::cref(b), std::cref(ts)... }, CompT<T>{});
}

Online Demo

在不是所有类型都相同的情况下,还可以添加适当的static_assert来改进错误消息。

答案 1 :(得分:0)

您可以使用std::min_element

auto lst = {4, 3, 1, 2, 5};
auto iter = std::min_element(std::begin(lst), std::end(lst));
std::cout << *iter << '\n'; // 1