是否有一个接受映射函数的min_element变体?

9

std::min_element函数将返回最小元素,其定义可以通过operator<(T,T)或自定义谓词bool Pred(T,T)来确定。是否有类似的函数,它返回投影函数f(T)->R取得最小值的元素?

显然,我可以定义bool Pred(t1,t2) { return f(t1) < f(t2); },但当f是lambda函数时,这有点不方便。


2
计算f的导数。好的好的我知道那是一个糟糕的玩笑 - Bartek Banachewicz
1
如果f是一个lambda函数,你可以将它传递给C++1y高阶多态lambda表达式[]( auto f ) { return [](auto t1, auto t2){ return f(t1) < f(t2); }; }(我想我已经平衡了括号)。当然,这会比你需要的计算量多一倍。 - Potatoswatter
你是否正在寻找一种方法,可以不必重复编写你的投影 R(T),同时又不会使其混乱外部范围? - Filip Roséen - refp
@refp: 这就是问题的要点。 - MSalters
@MSalters 不,高阶函数可以保留在头文件中。(建议有些开玩笑,但实际答案最终非常相似。) - Potatoswatter
显示剩余3条评论
2个回答

5

为什么不使用Boost.Iterator库中的boost::transform_iterator(曾经称为projection_iterator_adaptor)呢?

它可以帮助你完成这个任务。
auto Pred = [](some_value_type const& x){ /* your lambda here */ };
auto result = std::min_element(
    boost::make_transform_iterator(begin(container), Pred),    
    boost::make_transform_iterator(end(container), Pred)
).base(); 
//^^^^^^^  <-- to get back an iterator to the original sequence

这种方法的优势在于,您可以将其用于所有其他算法(例如对于std :: max_element ,您需要一个特殊的greater谓词等),而不是编写一个特殊的less谓词。

4
为什么不直接定义一个谓词生成器 less_by,它接受一个 lambda 表达式,并返回一个函数对象,以完成您的任务呢?
template <typename Proj>
struct less_by_t {
    Proj p;

    template <typename T>
    bool operator ()(T const& a, T const& b) const {
        return p(a) < p(b);
    }
};

template <typename Proj>
less_by_t<Proj> less_by(Proj p) {
    return {p};
}

auto result = std::min_element(begin, end, less_by([](T const& x){return …;}));

不错,但如果 Proj 很昂贵怎么办? - Nick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接