目前我正在学习标准模板库(STL)。
在这个程序中,我将一些长值存储在Associative Container中,然后根据单位的位置对它们进行排序(根据单位的数量)。
代码:
#include <iostream>
#include <set>
#include <functional>
using namespace std;
class UnitLess
{
public:
bool operator()(long first, long second)
{
long fu = first % 10;
long su = second % 10;
return fu < su;
}
};
typedef set<long, UnitLess> Ctnr;
int main(void)
{
Ctnr store;
store.insert(3124);
store.insert(5236);
store.insert(2347);
store.insert(6415);
store.insert(4548);
store.insert(6415);
for(Ctnr::iterator i = store.begin(); i != store.end(); ++i)
{
cout << *i << endl;
}
}
但是我不明白为什么我们的教授有过载()操作符?
感谢。
答案 0 :(得分:7)
UnitLess
是binary predicate,需要在STL中使用两个参数进行调用。
通过重载UnitLess
中该函数的函数调用操作符,可以像使用两个longs
并返回bool
的函数一样使用。
UnitLess f;
f(5, 10);
相当于
bool f(long first, long second)
{
long fu = first % 10;
long su = second % 10;
return fu < su;
}
f(5, 10);
答案 1 :(得分:7)
该类的目的是实现一个以给定方式对集合中的元素进行排序的函数。这被称为谓词。
它是作为一个仿函数实现的,即允许在一个对象上使用函数运算符(这就是std :: set在引擎盖下做的事情)。这样做是STL和类似代码调用自定义对象的常用方法。 (函数指针比函数对象(a.k.a. functor)更受限制
所以它的用法如下:
Unitless functor;
functor(123, 124); // returns true or false
std :: set是一个已排序的二叉树,因此它会在每个插入上多次调用Unitless的() - 运算符,以确定每个long值的位置。
尝试编译并在其中放置一些printf / std :: cout,看看会发生什么。
另外,请注意这样的回调(即当您看不到对代码的调用时)在学习曲线的开头是可怕且令人困惑的。
)
答案 2 :(得分:2)
他已经实现了一个用于std :: set的自定义比较,它只比较单位,即模数为10的数量。因为std :: set是一个模板,它只是试图调用看起来像函数的东西,无论是否它是一个与否。通过重载operator(),你可以使它像一个函数。
在某些情况下,这样做实际上非常强大,因为struct / class可以存储状态以及额外的参数。整个boost :: function / boost :: bind基于这样做(并且你不需要每次都创建一个类)。
在编码的实际示例中,可能存在轻微的缺陷,因为练习只是按单位对它们进行排序,但它可以很好地消除具有相同单位但实际上不重复的数字。在您的示例代码中没有这样的示例(您有重复但是它是整个值的副本)。如果除了4548之外还有3478,则Set比较器会认为它们是相同的,并且不允许复制。
顺便说一下,我不确定set是什么叫做“关联”容器,它指的是键值对。集合中没有关联的值,只有键。
还有一点:operator()应该是const。