关联容器,比较函数不是元素类型的一部分吗?

Associative containers, is the comparison function not part of element type?

本文关键字:类型 元素 一部分 比较 函数 关联      更新时间:2023-10-16

我认为,可以传递给关联容器模板(如std::setstd::multiset)的比较函数不是实例化容器类型实际element type的一部分吗?

#include <iostream>
#include <set>
#include "Sales_data_ex1119.hpp"
using namespace std;
bool compare_isbn(const Sales_data& lhs, const Sales_data& rhs) {
return lhs.isbn() < rhs.isbn();
}
int main() {
using cmp_func = bool (*)(const Sales_data& lhs, const Sales_data& rhs);
multiset<Sales_data, cmp_func> bookstore(&compare_isbn);
Sales_data foo("978", 2, 22.22);
Sales_data foo2("978", 2, 22.22);
Sales_data bar("979", 3, 22.22);
Sales_data baz("980", 2, 22.22);
bookstore.insert(foo);
bookstore.insert(foo2);
bookstore.insert(bar);
bookstore.insert(baz);
// comparsion function is not part of element type?
multiset<Sales_data>::iterator it = bookstore.begin();
while (it != bookstore.end()) {
print(cout, *it++);
cout << "n";
}
cout << "n";
// but the comparsion function can be applied also
multiset<Sales_data, cmp_func>::iterator it2 = bookstore.begin();
while (it2 != bookstore.end()) {
print(cout, *it2++);
cout << "n";
}   
return 0;
}

itit2这两个定义都可以在GCC 7中编译和运行良好。这对我来说是有道理的,key_type被定义为Sales_datastd::setstd::multisetkey_typeelement type.
如果看到很多人在定义中使用比较函数,这可能只是更明确但不是必需的。

谢谢

我认为,可以传递给关联容器模板(如 std::set 或 std::multiset)的比较函数不是实例化容器类型的实际元素类型的一部分?

迭代器进入multiset<Key,Compare,Allocator>的唯一完全可靠的类型是multiset<Key,Compare,Allocator>::iterator

现在,因为多集中的每个节点实际上都不需要排序顺序或分配器来完成它的工作,并且因为库编写者更喜欢避免重复,所以很有可能在你的标准库中的某个地方有一个迭代器类模板,该模板在所有(multi)(set|map)类之间共享, 这仅取决于元素类型。

但如果是这种情况,它是一个实现细节,是不可移植的,并且可能会发生变化。所以,这个:

multiset<Sales_data, cmp_func> bookstore(&compare_isbn);
multiset<Sales_data>::iterator it = bookstore.begin();

目前可能很有效。但是另一个编译器或库实现拒绝它是完全合法的。

无论如何,即使不包括比较(和分配器!)类型参数,写出整个事情也是非常乏味的。只需使用

auto it = bookstore.begin()

忘记整件事。或者,更好的是:

for (auto &sale : bookstore) {

或者,在特定情况下,编写流插入运算符并使用

copy(begin(bookstore), end(bookstore),
ostream_iterator<Sales_data>(cout, "n"));