簡體   English   中英

在一元函數上使用 STL 算法

[英]Using STL algorithms on unary functions

所以我經常想對一系列元素執行一些 STL 算法,而不是比較 function,我想傳遞一元 function f。

例如我想寫這樣的東西

std::max_element(begin(range), end(range), f);

在應用 f 后找到范圍內的最大元素。 我目前的解決方法看起來像這樣:

std::max_element(begin(range), end(range, [&f](auto a, auto b){ return f(a) < f(b); });

乍一看,這似乎沒有問題。 但是 f 可能是 lambda 表達式本身,或者以另一種方式比 f 更復雜。 我對那段代碼有兩個問題:a)它很容易出錯,因為人們可能會不小心寫出 f(a) < f(a) (特別是如果更復雜並且使用了副本和過去)。 這是代碼重復的問題 b) 它沒有很好地表達意圖。 如果我想按 function 排序,我不想處理比較。

不幸的是,我在標准庫(甚至是boost)中沒有找到解決這類問題的好方法,所以我想問一下你對這個問題的解決方案是什么。 算法中不存在這種重載有什么原因嗎?

使用 c++ 20 的范圍,您可以:

std::ranges::max_element(range | std::views::transform(f));

您可以做的一件事是創建自己的通用比較器,該比較器接受一元 function 來執行轉換:

// Generic comparator
template<typename T, typename F>
struct transform_comparator_type
{
    transform_comparator_type(F f): f(f) {}
    bool operator()(T const& a, T const& b) const { return f(a) < f(b); }
    F f;
};

// Helper function to deduce the type of F
template<typename T, typename F>
auto transform_comparator(F f)
{
    return transform_comparator_type<T, F>(f);
}

int main()
{
    std::vector<int> v{1, 4, 3, 6, 0};

    auto e = std::max_element(std::begin(v), std::end(v),
        transform_comparator<int>([v](int i){ return 2 * i; }));

    // etc...
}

編輯添加:

該類型實際上可以從提供的變換 function 的返回類型推導出來,因此您不需要幫助器 function。 你可以這樣做:

template<typename F>
struct transform_comparator
{
    using T = decltype(F()({})); // deduce T from return type of F
    transform_comparator(F f): f(f) {}
    bool operator()(T const& a, T const& b) const { return f(a) < f(b); }
    F f;
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM