【问题标题】:Succinct implementation of min() that returns minimum of multiple valuesmin() 的简洁实现,返回多个值中的最小值
【发布时间】:2023-04-09 14:13:01
【问题描述】:

使用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。

【问题讨论】:

  • 为什么不使用std::min({a, b, c})、std::min({a, b, c, d, e})等?这是开箱即用的,并且是 constexpr。
  • 我看不出你的第一个版本有什么问题。为什么要限制单一功能?请记住,它是一个模板,并且会为每次调用生成一个函数(使用不同的Ts),所以这个限制似乎毫无意义。
  • @ildjarn 如果a、b、c 等复制成本很高,或者根本无法复制怎么办?
  • @ildjarn 该问题与this有关。

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


【解决方案1】:

我会咬人的:

#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 以改进在并非所有类型都相同的情况下的错误消息。

【讨论】:

  • 巧妙!它还允许对谓词进行一定程度的定制。不过也有一些小问题。 This 应该是要发布的版本。
  • @Lingxi :迂腐地,这允许单参数调用(这没有意义),并且提供的是比较器,而不是谓词。 ;-]
  • 学究式,既然std::min() 允许,我们也应该这样做;-]
  • @Lingxi : 够公平!
  • 更不用说偏序集的数学概念了,它允许一个元素的集合。虽然答案很可靠。
【解决方案2】:

你可以使用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

【讨论】:

    猜你喜欢
    • 2019-12-15
    • 2012-10-29
    • 2020-06-07
    • 2018-11-01
    • 2014-09-09
    • 2016-04-14
    • 1970-01-01
    • 2015-09-01
    • 2023-03-30
    相关资源
    最近更新 更多