值得一提的是,表 1 中的这些排序规则,其底层也是采用函数对象的方式实现的。以 std::less<T> 为例,其底层实现为:
template <typename T>
struct less {
//定义新的排序规则
bool operator()(const T &_lhs, const T &_rhs) const {
return _lhs < _rhs;
}
}
在此基础上,当关联式容器中存储的数据类型为自定义的结构体变量或者类对象时,通过对现有排序规则中所用的关系运算符进行重载,也能实现自定义排序规则的目的。 注意,当关联式容器中存储的元素类型为结构体指针变量或者类的指针对象时,只能使用函数对象的方式自定义排序规则,此方法不再适用。 举个例子:
#include <iostream>
#include <set> // set
#include <string> // string
using namespace std;
//自定义类
class myString {
public:
//定义构造函数,向 myset 容器中添加元素时会用到
myString(string tempStr) :str(tempStr) {};
//获取 str 私有对象,由于会被私有对象调用,因此该成员方法也必须为 const 类型
string getStr() const;
private:
string str;
};
string myString::getStr() const{
return this->str;
}
//重载 < 运算符,参数必须都为 const 类型
bool operator <(const myString &stra, const myString & strb) {
//以字符串的长度为标准比较大小
return stra.getStr().length() < strb.getStr().length();
}
int main() {
//创建空 set 容器,仍使用默认的 less<T> 排序规则
std::set<myString>myset;
//向 set 容器添加元素,这里会调用 myString 类的构造函数
myset.emplace("http://jb51.net.net/stl/");
myset.emplace("http://jb51.net.net/c/");
myset.emplace("http://jb51.net.net/python/");
//
for (auto iter = myset.begin(); iter != myset.end(); ++iter) {
myString mystr = *iter;
cout << mystr.getStr() << endl;
}
return 0;
}
在这个程序中,虽然 myset 容器表面仍采用默认的 std::less<T> 排序规则,但由于我们对其所用的 < 运算符进行了重载,使得 myset 容器内部实则是以字符串的长度为基准,对各个 mystring 类对象进行排序。 另外,上面程序以全局函数的形式实现对 < 运算符的重载,还可以使用成员函数或者友元函数的形式实现。其中,当以成员函数的方式重载 < 运算符时,该成员函数必须声明为 const 类型,且参数也必须为 const 类型:
bool operator <(const myString & tempStr) const {
//以字符串的长度为标准比较大小
return this->str.length() < tempStr.str.length();
}
至于参数的传值方式是采用按引用传递还是按值传递,都可以(建议采用按引用传递,效率更高)。 同样,如果以友元函数的方式重载 < 运算符时,要求参数必须使用 const 修饰:
//类中友元函数的定义
friend bool operator <(const myString &a, const myString &b);
//类外部友元函数的具体实现
bool operator <(const myString &stra, const myString &strb) {
//以字符串的长度为标准比较大小
return stra.str.length() < strb.str.length();
}
当然,本节所讲自定义排序规则的方法并不仅仅适用于 set 容器,其它关联式容器(map、multimap、multiset)也同样适用,有兴趣的读者可自行编写代码验证。 到此这篇关于C++ STL关联式容器自定义排序规则的2种方法的文章就介绍到这了,更多相关C++ STL关联式容器自定义排序内容请搜索社区以前的文章或继续浏览下面的相关文章希望大家以后多多支持社区! | |||||||||||