简体   繁体   English

C ++ STL sort()函数,二元谓词

[英]C++ STL sort() function, binary predicate

I have a piece of code that confuses me: 我有一段令我困惑的代码:

   sort(data, data+count, greater<int>() );

it is a sort function in the C standard library. 它是C标准库中的排序函数。 I am having trouble figuring out the meaning of the third argument. 我无法弄清楚第三个论点的含义。 I have read that it is called a binary predicate. 我已经读过它被称为二元谓词。 What does that mean and how can I make my own such predicate? 这意味着什么?我如何制作自己的谓词?

The third argument is called a predicate . 第三个参数称为谓词 You can think of a predicate as a function that takes a number of arguments and returns true or false . 您可以将谓词视为一个函数,它接受许多参数并返回truefalse

So for example, here is a predicate that tells you whether an integer is odd: 因此,例如,这是一个谓词,告诉您整数是否为奇数:

bool isOdd(int n) {
    return n & 1;
}

The function above takes one argument, so you could call it a unary predicate. 上面的函数有一个参数,所以你可以把它称为一元谓词。 If it took two arguments instead, you would call it a binary predicate. 如果改为使用两个参数,则将其称为二元谓词。 Here is a binary predicate that tells you if its first argument is greater than the second: 这是一个二元谓词,告诉你它的第一个参数是否大于第二个:

bool isFirstGreater(int x, int y) {
    return x > y;
}

Predicates are commonly used by very general-use functions to allow the caller of the function to specify how the function should behave by writing their own code (when used in this manner, a predicate is a specialized form of callback ). 谓词通常由非常通用的函数使用,以允许函数的调用者通过编写自己的代码来指定函数的行为(当以这种方式使用时,谓词是一种特殊形式的回调 )。 For example, consider the sort function when it has to sort a list of integers. 例如,在必须对整数列表进行排序时,请考虑sort函数。 What if we wanted it to sort all odd numbers before all even ones? 如果我们想要在所有偶数之前对所有奇数进行排序怎么办? We don't want to be forced to write a new sort function each time that we want to change the sort order, because the mechanics (the algorithm) of the sort is clearly not related to the specifics (in what order we want it to sort). 每次我们想要更改排序顺序时,我们不希望被强制编写新的排序函数,因为排序的机制(算法)显然与细节无关(我们希望它以什么顺序)分类)。

So let's give sort a predicate of our own to make it sort in reverse: 所以,让我们给sort一个我们自己的谓语,使其排序相反:

// As per the documentation of sort, this needs to return true
// if x "goes before" y. So it ends up sorting in reverse.
bool isLarger(int x, int y) {
    return x > y;
}

Now this would sort in reverse order: 现在这将按相反的顺序排序:

sort(data, data+count, isLarger);

The way this works is that sort internally compares pairs of integers to decide which one should go before the other. 其工作原理是sort内部比较对的整数来决定哪些应该先于另一个去。 For such a pair x and y , it does this by calling isLarger(x, y) . 对于这样的一对xy ,它通过调用isLarger(x, y)

So at this point you know what a predicate is, where you might use it, and how to create your own. 所以在这一点上你知道谓词是什么,你可以在哪里使用它,以及如何创建自己的谓词。 But what does greater<int> mean? 但是greater<int>是什么意思?

greater<T> is a binary predicate that tells if its first argument is greater than the second. greater<T>是一个二元谓词,它告诉它的第一个参数是否大于第二个参数。 It is also a templated struct , which means it has many different forms based on the type of its arguments. 它也是一个模板化的struct ,这意味着它根据其参数的类型有许多不同的形式。 This type needs to be specified, so greater<int> is the template specialization for type int (read more on C++ templates if you feel the need). 这种类型的需要指定,所以greater<int>是类型的模板专业化 int (阅读更多关于C ++模板,如果你觉得有必要)。

So if greater<T> is a struct , how can it also be a predicate? 因此,如果greater<T>是一个struct ,它怎么也可以是一个谓词? Didn't we say that predicates are functions ? 我们不是说谓词是函数吗?

Well, greater<T> is a function in the sense that it is callable : it defines the operator bool operator()(const T& x, const T& y) const; 好吧, greater<T>是一个函数,它是可调用的 :它定义了运算符bool operator()(const T& x, const T& y) const; , which makes writing this legal: ,这使得写这个合法:

std::greater<int> predicate;
bool isGreater = predicate(1, 2); // isGreater == false

Objects of class type (or struct s, which is pretty much the same in C++) which are callable are called function objects or functors . 可调用的类类型(或struct ,在C ++中几乎相同)的对象称为函数对象仿函数

There is a class template called greater which needs a type argument. 有一个名为greater的类模板需要一个类型参数。 So you provide int as one. 所以你提供int作为一个。 It became greater<int> and you create an instance of this class and pass it to the function as third argument. 它变得greater<int>并且您创建此类的实例并将其作为第三个参数传递给函数。

Such an object is called function object or simply functor in C++, as the class overloads () operator. 这样的对象在C ++中称为函数对象或简称为functor ,作为类的overload ()运算符。 It's a callable entity. 它是一个可调用的实体。 Its like this: 就像这样:

template<typename T>
struct greater
{
   bool operator()(const T &a, const T &b)
   {
      //compare a and b and return either true or false.
      return a > b;
   }
};

If you create an instance of greater<int> and, say, the object is g , then you can write g(100,200) which evaluates to a boolean value, as the expression g(100,200) calls operator() , passing 100 as first argument and 200 as second argument, and operator() compares them and return either true or false . 如果你创建一个greater<int>的实例,比如说,对象是g ,那么你可以编写g(100,200) ,其值为布尔值,因为表达式g(100,200)调用operator() ,首先传递100参数和200作为第二个参数, operator()比较它们并返回truefalse

       std::cout << g(100,200) << std::endl;
       std::cout << g(200,100) << std::endl;

Output: 输出:

0
1

Online demo : http://ideone.com/1HKfC 在线演示: http//ideone.com/1HKfC

A binary predicate is any function/object that receives two objects (hence binary) and returns a bool (hence predicate ); 二元谓词是接收两个对象(因此是二进制)并返回bool (因此谓词 )的任何函数/对象; the idea is that it evaluates if the two objects satisfy some particular condition - in the example, if one is greater than the other. 我们的想法是评估两个对象是否满足某些特定条件 - 在本例中,如果一个对象大于另一个对象。

You can create a predicate either by just defining a function with the correct signature 您可以通过仅使用正确的签名定义函数来创建谓词

bool IsIntGreater(int First, int Second)
{
    return First>Second;
}

and passing the name of the function as the argument (this will result in passing a function pointer), or creating a function object (a functor ), ie an object which overloads the function call operator and thus can be used as a function; 并将函数的名称作为参数传递(这将导致传递函数指针),或者创建一个函数对象( 仿函数 ),即一个重载函数调用操作符的对象,因此可以用作函数; the std::greater<T> type is a template functor, and in your snippet a temporary object of type std::greater<int> is created and passed to the std::sort algorithm. std::greater<T>类型是模板函子,在你的代码片段中创建了一个std::greater<int>类型的临时对象并传递给std::sort算法。

Functors have several advantages over functions, especially when they have to be passed as arguments, have a look here for more information about this. 函数有几个优于函数的优点,特别是当它们必须作为参数传递时,请查看此处以获取有关此函数的更多信息。

See comp in http://www.cplusplus.com/reference/algorithm/sort/ 请参阅http://www.cplusplus.com/reference/algorithm/sort/中的 comp

It is the function that does the comparison. 这是进行比较的功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM