c++ - 通过函数调用在 C++ 数组上取最大值

标签 c++

我有一个 obj 对象列表,每个对象都有一个 eval() 方法,返回一个 double。我想获得所有这些的最大值。到目前为止,我一直都是这样做的

double maxval = std::numeric_limits<double>::lowest();
for (const auto &obj: objs) {
  maxval = std::max(maxval, obj->eval());
}

我想知道是否有更优雅的解决方案,您不必设置初始值-inf,类似于 Python 的

max_value = max(obj.eval() for obj in objs)

也许吧。请注意 eval() 可能很昂贵,所以我只想为每个 obj eval() 一次。

有什么提示吗?可读性加分。

最佳答案

一些 <ranges>好东西(仅限 C++20):

#include <ranges>

const auto maxval = std::ranges::max_element(objs, std::less<>{}, &ObjType::eval);

if (maxval != objs.cend())
    doStuffWith(*maxval);

哪里ObjType是序列元素的类型。最后一次检查也可能是关于容器的大小 maxval当序列不为空时,肯定是一个可取消引用的迭代器,例如

if (!objs.empty()) ; // ...

但是请注意,正如@NathanOliver 指出的那样,这会调用 eval() 2N-2次。这是一个自定义模板,将调用 eval()恰好 N 次:

#include <optional>
#include <functional>
#include <type_traits>

template <class Range, class Cmp = std::less<>, class Proj = std::identity>
auto maxValue(const Range& rng, Cmp pred = Cmp{}, Proj p = Proj{})
{
    using std::begin;
    using std::end;
    using ValueType = std::remove_cvref_t<std::invoke_result_t<Proj,
        decltype(*begin(rng))>>;

    auto first = begin(rng);
    const auto last = end(rng);

    if (first == last)
        return std::optional<ValueType>{};

    auto result = std::invoke(p, *first);

    for (++first; first != last; ++first)
        result = std::max(std::invoke(p, *first), result, pred);

    return std::optional{result};
}

它不返回迭代器,而是返回结果值 - 包装到 std::optional 中如果范围为空(则结果为 std::nullopt )。类型的用法 Test具有成员函数 Test::eval()会是这样的:

const auto max = maxValue(myContainer, std::less<>{}, &Test::eval);

第二个和第三个参数具有合理的默认值,因此对于原始类型等,它们可以被忽略。

关于c++ - 通过函数调用在 C++ 数组上取最大值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67838347/

相关文章:

c++ - 当我四处移动我的 Sprite 时,它一直在离开窗口

c++ - clang6 实现 std::可选 吗?

c++ - 在 C++ 中避免标签缩进

c++ - 具有背景图像和其他透明背景的 QFrame

c++ - getline(cin, name) 导致看似永无止境的输入提示

c++ - 逐行读取文件,并存储为字符串

c++ - MSBuild入参配置

c++ - 为什么 RegisterClass 因 ERROR_NOT_ENOUGH_MEMORY 而失败?

c++ - 使用 `std::reference_wrapper<T>` 作为始终有效的成员变量而不是指针有什么缺点吗?

c++ - opencv分割返回黑色图像