C++ C++;STL sort()函数,二进制谓词

C++ C++;STL sort()函数,二进制谓词,c++,sorting,stl,C++,Sorting,Stl,我有一段代码让我困惑: sort(data, data+count, greater<int>() ); 排序(数据,数据+计数,更大()); 它是C标准库中的一个排序函数。我很难理解第三个论点的含义。我读过,它被称为二元谓词。这意味着什么?我如何创建自己的此类谓词?有一个名为greater的类模板,它需要一个类型参数。因此,您将int作为一个整体提供。它变得更大了,您创建了这个类的一个实例,并将其作为第三个参数传递给函数 > C++中调用此类对象,因为类重载()代码>运

我有一段代码让我困惑:

   sort(data, data+count, greater<int>() );
排序(数据,数据+计数,更大());

它是C标准库中的一个排序函数。我很难理解第三个论点的含义。我读过,它被称为二元谓词。这意味着什么?我如何创建自己的此类谓词?

有一个名为
greater
的类模板,它需要一个类型参数。因此,您将
int
作为一个整体提供。它变得更大了,您创建了这个类的一个实例,并将其作为第三个参数传递给函数

<> > C++中调用此类对象,因为类重载<代码>()<>代码>运算符。它是一个可调用的实体。它是这样的:

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;
   }
};
输出:

0
1
在线演示:

请参见中的
comp


它是进行比较的函数。

第三个参数称为a。您可以将谓词视为一个函数,它接受许多参数并返回
true
false

       std::cout << g(100,200) << std::endl;
       std::cout << g(200,100) << std::endl;
例如,这里有一个谓词,告诉你一个整数是否是奇数:

bool isOdd(int n) {
    return n & 1;
}
上面的函数接受一个参数,因此可以将其称为谓词。如果取而代之的是两个参数,则称之为谓词。下面是一个二进制谓词,告诉您其第一个参数是否大于第二个参数:

bool isFirstGreater(int x, int y) {
    return x > y;
}
谓词通常由非常通用的函数使用,以允许函数的调用方通过编写自己的代码来指定函数的行为(以这种方式使用时,谓词是函数的一种特殊形式)。例如,当必须对整数列表进行排序时,考虑<代码>排序< /COD>函数。如果我们想让它把所有奇数排在所有偶数之前呢?我们不希望每次更改排序顺序时都被迫编写一个新的排序函数,因为排序的机制(算法)显然与细节无关(我们希望排序的顺序)

因此,让我们给
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;
}
现在,这将按相反的顺序排序:

sort(data, data+count, isLarger);
其工作方式是,
sort
在内部比较整数对,以决定哪一个应该在另一个之前。对于这样一对
x
y
,它通过调用
isLarger(x,y)
来实现这一点

因此,在这一点上,您知道什么是谓词,在哪里可以使用它,以及如何创建自己的谓词。但是
更大的
意味着什么呢

是一个二元谓词,用于判断其第一个参数是否大于第二个参数。它也是一个模板化的
结构
,这意味着它根据参数的类型有许多不同的形式。需要指定这个类型,所以<>代码> Gealth是类型<代码> int 的模板特化(如果您觉得需要,请阅读C++模板中的更多内容)。 因此,如果
greater
是一个
struct
,它又怎么可能是一个谓词呢?我们不是说过谓词是函数吗

好的,
greater
是一个可以调用的函数:它定义了操作符
bool operator()(const T&x,const T&y)const,这使得编写此代码合法:

std::greater<int> predicate;
bool isGreater = predicate(1, 2); // isGreater == false
std::更大谓词;
bool ismorer=谓词(1,2);//isGreater==false

类类型的对象(或
struct
s,在C++中几乎相同)是可调用的,称为或函子。

二元谓词是接收两个对象(因此是二进制的)并返回
bool
(因此)的任何函数/对象;其思想是,它评估两个对象是否满足某些特定条件——在本例中,如果一个大于另一个

您可以通过定义具有正确签名的函数来创建谓词

bool IsIntGreater(int First, int Second)
{
    return First>Second;
}
并将函数名作为参数传递(这将导致传递函数指针),或创建函数对象(函子),即重载函数调用运算符并因此可用作函数的对象;
std::greater
类型是一个模板函子,在代码段中创建一个类型为
std::greater
的临时对象,并将其传递给
std::sort
算法


函子比函数有几个优点,特别是当它们必须作为参数传递时,请查看有关这方面的更多信息。

我怀疑这个大型示例仍然会按升序排序<代码>较大值
使其按降序排序。但在
排序中(数据、数据+计数、isSmaller)
你从来没有提到过
x
y
isSmaller
如何知道要比较什么?@Niello:在
排序
调用后添加了一个小解释。这足够了吗?啊,那么x和y基本上代表要排序的数组元素?正确的?当排序过程完成时,它会检查元素的顺序?@Niello:是的,没错。决定要比较哪些元素对、何时比较它们以及如何处理比较结果都是排序算法的一部分(因此您不能影响这一点)。但是使用回调(或者谓词,如果您愿意的话),您可以决定比较结果是什么。