簡體   English   中英

如何在C ++中為copy_if等定義“一元謂詞”?

[英]How do I define a “unary predicate” for copy_if, etc in C++?

我正在嘗試使用std :: copy_if(),並且從http://www.cplusplus.com/reference/algorithm/copy_if/弄清楚了該語法的工作原理:

auto it = std::copy_if (foo.begin(), foo.end(), bar.begin(), [](int i){return !(i<0);} );

最后一個論點是我感到困惑的一個。 括號用於什么? 我可以使用在其他地方編寫的函數作為參數,它如何工作? 如果指定要傳遞給該函數的變量,是否可以將另一個參數傳遞給該函數?

我想我的總體問題是我在哪里可以找到這些語法。 使用此示例,我可以聲明一些非常簡單的內容,但是我希望能夠做更多的事情。 我已經找到了一些地方來解釋一元謂詞應該做什么和不應該做什么,但是實際上卻沒有解釋如何聲明一個謂詞以及這意味着什么。 我對c ++中的算法還是有些陌生,希望能學習如何更有效地使用它們。

您可以將行為類似於函數的任何內容作為謂詞傳遞給copy_if 您可以使用一些常用的東西:

1)功能

函數的作用確實類似於函數,因此可以將它們作為謂詞傳遞給copy_if

bool is_less_than_zero(int i) { return i < 0; }

int main() {
    std::vector<int> a = {1, 2, -2, -1};
    std::vector<int> b;

    std::copy_if(a.begin(), a.end(), std::back_inserter(b), is_less_than_zero);
    // now b will contain the elements {-2, -1}
}

現場演示

2)具有重載operator()對象

對象可以重載operator()以便它們像函數一樣起作用。 這些通常稱為“功能對象”或“功能部件”。 這可以讓您存儲狀態,這是原始功能無法實現的:

struct IsLessThan {
    IsLessThan(int i) : i_{i} {}
    bool operator()(int i) { return i < i_; }
    int i_;
};

int main() {
    std::vector<int> a = {1, 2, -2, -1};
    std::vector<int> b;

    std::copy_if(a.begin(), a.end(), std::back_inserter(b), IsLessThan(0));
    // now b will contain the elements {-2, -1}
}

現場演示

3) Lambdas

Lambda在概念上是匿名函數。 實際上,它們只是帶有重載operator()對象的語法糖,但這使它們成為用很少的代碼創建簡單謂詞的有用工具:

int main() {
    std::vector<int> a = {1, 2, -2, -1};
    std::vector<int> b;

    std::copy_if(a.begin(), a.end(), std::back_inserter(b),
                 [](int i){ return i < 0; });
    // now b will contain the elements {-2, -1}
}

現場演示

由於lambda實際上是帶有重載operator()對象,因此它們也可以包含狀態,該狀態通過lambda的捕獲列表給出:

int main() {
    std::vector<int> a = {1, 2, -2, -1};
    std::vector<int> b;
    int number_to_compare_to = 0;

    std::copy_if(a.begin(), a.end(), std::back_inserter(b),
                 [number_to_compare_to](int i){ return i < number_to_compare_to; });
    // now b will contain the elements {-2, -1}
}

現場演示

標准庫中有一些功能可以輕松創建包含狀態的函數對象,並使用它為函數提供一些參數(即std::bind ),但是在大多數有用的地方,使用a現在更容易lambda代替。 也就是說,以下代碼創建兩個對象,它們的行為完全相同:

bool first_less_than_second(int i, int j) { return i < j; }

int main() {
    auto bind_less_than_zero = std::bind(first_less_than_second, std::placeholders::_1, 0);
    auto lambda_less_than_zero = [](int i){ return first_less_than_second(i, 0); };
}

通常,您應該更喜歡lambda版本,但有時仍會看到使用std::bind (或其c ++ 11之前的Boost對應的boost::bind )。

暫無
暫無

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

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