如何定义“一元谓词"?用于C ++中的copy_if等? [英] How do I define a "unary predicate" for copy_if, etc in C++?

查看:50
本文介绍了如何定义“一元谓词"?用于C ++中的copy_if等?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用std :: copy_if(),并且从

I'm trying to use std::copy_if() and I figured out somewhat how the syntax works from http://www.cplusplus.com/reference/algorithm/copy_if/ :

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

最后一个参数是我很困惑的那个.括号是用来干什么的?我可以使用在其他地方编写的函数作为参数,这将如何工作?如果我指定要传递给该函数的变量,是否可以将另一个参数传递给该函数?

The last argument is the one that I am confused about. What are the brackets for? Can I use a function I wrote somewhere else as an argument and how would that work? Can I pass another argument to the function if I specify which variable to pass to it?

我想我的总体问题是,我在哪里可以找到这些语法.使用此示例,我可以声明一些非常简单的内容,但是我希望能够做更多的事情.我已经找到了一些地方来解释一元谓词应该做什么和不应该做什么,但是实际上却没有解释如何声明一个一元谓词以及这意味着什么.我对c ++中的算法还是有些陌生,希望学习如何更有效地使用它们.

I guess my overall question is where I could find the syntax for these things. Using this example, I can declare some really simple things, but I'd like to be able to do more with it. I've found a few places that explain what a unary predicate should do and not do, but not actually how to declare one and what that would mean. I'm still somewhat new to the algorithms in c++ and hope to learn how to use them more effectively.

推荐答案

您可以将行为类似于函数的任何内容作为谓词传递给 copy_if .您可以使用一些常用的东西:

You can pass anything that behaves like a function as the predicate to copy_if. There are a few common things you can use:

1)功能

函数的作用确实类似于函数,因此可以将它们作为谓词传递给 copy_if :

Functions indeed act like functions, so they can be passed as a predicate to 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(),以便它们像函数一样起作用.这些通常称为功能对象"或功能部件".这可以让您存储状态,这是原始功能无法实现的:

Objects can overload operator() so that they act like functions. These are often called "function objects" or "functors". This lets you store state, which can't be achieved with raw functions:

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()重载的对象的语法糖,但这使它们成为创建少量代码的简单谓词的有用工具:

Lambdas are conceptually anonymous functions. In reality, they're just syntactic sugar for objects with an overloaded operator(), but that makes them a useful tool for creating simple predicates with little code:

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的捕获列表给出:

Since lambdas are really objects with an overloaded operator() they can also contain state, which is given via the lambda's capture list:

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}
}

实时演示

标准库中有一些功能可以轻松创建包含状态的函数对象,并使用它为函数提供一些参数(即

There are some facilities in the standard library to easily create function objects that contain state and use it to supply some of the parameters to a function (namely std::bind), but most of the places they were useful it's now easier to use a lambda instead. That is, the following code creates two objects that both act exactly the same:

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 :: bind >)受雇.

In general you should prefer the lambda version, but you will still sometimes see std::bind (or its pre-c++11 boost counterpart boost::bind) employed.

这篇关于如何定义“一元谓词"?用于C ++中的copy_if等?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆