C++ 最大值超过c++;带函数调用的数组
我有一个C++ 最大值超过c++;带函数调用的数组,c++,C++,我有一个obj对象列表,每个对象都有一个eval()方法,返回一个double。我想得到所有这些的最大值。到目前为止,我一直在做 double maxval=std::numeric_limits::lowest(); 用于(常量自动和obj:objs){ maxval=std::max(maxval,obj->eval()); } 我想知道是否有一个更优雅的解决方案,您不必设置初始值-inf,类似于Python的 max_value=max(obj.eval()用于objs中的obj) 也
obj
对象列表,每个对象都有一个eval()
方法,返回一个double
。我想得到所有这些的最大值。到目前为止,我一直在做
double maxval=std::numeric_limits::lowest();
用于(常量自动和obj:objs){
maxval=std::max(maxval,obj->eval());
}
我想知道是否有一个更优雅的解决方案,您不必设置初始值-inf,类似于Python的
max_value=max(obj.eval()用于objs中的obj)
也许吧。请注意,eval()
可能很贵,因此我只想eval()
每obj
一次
有什么提示吗?可读性的奖励点。< /P> < P> C++相当于Python的代码> max < /C> >是./P>
auto-itr=std::max\u元素(
objs.begin(),objs.end(),
[](const auto&lhs,const auto&rhs){返回lhs.eval()
一些
好东西(仅限C++20):
但是请注意,正如@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};
}
第二个和第三个参数具有合理的默认值,因此对于基元类型和类似的类型,可以忽略它们。所以使用第一个参数的值的常规做法不适合您?为什么?@Yunnosch列表可能是空的。这会缓存
eval()
的结果吗?@NicoSchlömer我认为标准不需要缓存,所以它可能取决于标准库实现。它应该如何缓存结果?!这里没有涉及任何国家。它不能将结果写入全局变量,以便在下次调用时返回。我明白了。这是一个有趣的解决方案,但对我来说不是太有用eval()
可能很昂贵,所以我真的只想对每个对象执行一次eval()
。对每个obj
调用eval
的频率是多少?这是一个线性算法,所以每个对象执行一次。线性复杂度也可能意味着每个对象执行k次,例如,两次。这不是每个元素还需要两次调用eval
?即,调用e1 cmp e2
,然后调用e2 cmp e3
。。。因此,只有第一个和最后一个元素对它们调用了一次cmp
。看起来它被调用了2N-2
次:
#include <ranges>
const auto maxval = std::ranges::max_element(objs, std::less<>{}, &ObjType::eval);
if (maxval != objs.cend())
doStuffWith(*maxval);
if (!objs.empty()) ; // ...
#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};
}
const auto max = maxValue(myContainer, std::less<>{}, &Test::eval);