C++ 具名要求-全库范围的概念 - 建立一种顺序关系的二元谓词 (BinaryPredicate)

发布时间:2024年01月13日

此页面中列出的具名要求,是 C++ 标准的规范性文本中使用的具名要求,用于定义标准库的期待。

某些具名要求在 C++20 中正在以概念语言特性进行形式化。在那之前,确保以满足这些要求的模板实参实例化标准库模板是程序员的重担。若不这么做,则可能导致非常复杂的编译器诊断。

全库范围的概念
?

建立一种顺序关系的二元谓词 (BinaryPredicate)

C++ 具名要求: Compare

比较 (Compare) 是一些标准库设施针对用户提供的函数对象类型所期待的一组要求。

对满足比较 (Compare) 的类型的对象运用函数调用操作的返回值,当按语境转换成 bool 时,若此类型所引入的严格弱序关系中,该调用的第一实参先于第二实参,则生成 true,否则生成 false。

与任何二元谓词 (BinaryPredicate) 相同,不允许该表达式的求值通过解引用的迭代器调用非 const 函数。

要求

以下情况下,类型 T 满足比较 (Compare)

  • 类型 T 满足二元谓词 (BinaryPredicate) ,且

给定

  • T 类型的对象 comp
  • equiv(a, b),为等价于 !comp(a, b) &&?!comp(b, a) 的表达式

下列表达是必须合法且拥有其指定的效果

表达式返回类型要求
comp(a, b)可隐式转换为 bool建立具有下列性质的严格弱序关系
  • 对于所有 a,comp(a,a)==false
  • 若 comp(a,b)==true 则 comp(b,a)==false
  • 若 comp(a,b)==true 且 comp(b,c)==true 则 comp(a,c)==true
equiv(a, b)bool建立具有下列性质的等价关系
  • 对于所有 a,equiv(a,a)==true
  • 若 equiv(a,b)==true 则 equiv(b,a)==true
  • 若 equiv(a,b)==true 且 equiv(b,c)==true 则 equiv(a,c)==true

注:compequiv 所确定的等价类上引入了一种严格全序

标准库

下列标准库设施期待比较 (Compare) 类型。

set

唯一键的集合,按照键排序
(类模板)

map

键值对的集合,按照键排序,键是唯一的
(类模板)

multiset

键的集合,按照键排序
(类模板)

multimap

键值对的集合,按照键排序
(类模板)

priority_queue

适配一个容器以提供优先级队列
(类模板)

sort

将范围按升序排序
(函数模板)

sort

对元素进行排序
(std::forward_list<T,Allocator> 的公开成员函数)

sort

对元素进行排序
(std::list<T,Allocator> 的公开成员函数)

stable_sort

将范围内的元素排序,同时保持相等的元素之间的顺序
(函数模板)

partial_sort

排序一个范围的前 N 个元素
(函数模板)

partial_sort_copy

对范围内的元素进行复制并部分排序
(函数模板)

is_sorted

(C++11)

检查范围是否已按升序排列
(函数模板)

is_sorted_until

(C++11)

找出最大的已排序子范围
(函数模板)

nth_element

将给定的范围部分排序,确保其按给定元素划分
(函数模板)

lower_bound

返回指向第一个不小于给定值的元素的迭代器
(函数模板)

upper_bound

返回指向第一个大于给定值的元素的迭代器
(函数模板)

binary_search

确定元素是否存在于某范围中
(函数模板)

equal_range

返回匹配特定键值的元素范围
(函数模板)

merge

归并两个已排序的范围
(函数模板)

merge

合并二个已排序列表
(std::forward_list<T,Allocator> 的公开成员函数)

merge

合并二个已排序列表
(std::list<T,Allocator> 的公开成员函数)

inplace_merge

就地归并两个有序范围
(函数模板)

includes

若一个集合是另一个的子集则返回 true
(函数模板)

set_difference

计算两个集合的差集
(函数模板)

set_intersection

计算两个集合的交集
(函数模板)

set_symmetric_difference

计算两个集合的对称差
(函数模板)

set_union

计算两个集合的并集
(函数模板)

push_heap

将一个元素加入到一个最大堆
(函数模板)

pop_heap

从最大堆中移除最大元素
(函数模板)

make_heap

从一个元素范围创建出一个最大堆
(函数模板)

sort_heap

将一个最大堆变成一个按升序排序的元素范围
(函数模板)

is_heap

检查给定范围是否为一个最大堆
(函数模板)

is_heap_until

(C++11)

查找能成为最大堆的最大子范围
(函数模板)

max

返回各给定值中的较大者
(函数模板)

max_element

返回范围内的最大元素
(函数模板)

min

返回各给定值中的较小者
(函数模板)

min_element

返回范围内的最小元素
(函数模板)

minmax

(C++11)

返回两个元素的较小和较大者
(函数模板)

minmax_element

(C++11)

返回范围内的最小元素和最大元素
(函数模板)

lexicographical_compare

当一个范围按字典顺序小于另一个范围时,返回 true
(函数模板)

next_permutation

产生某个元素范围的按字典顺序的下一个较大的排列
(函数模板)

prev_permutation

产生某个元素范围的按字典顺序的下一个较小的排列
(函数模板)

调用示例

#include <iostream>
#include <string>
#include <iterator>
#include <algorithm>
#include <functional>
#include <time.h>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <forward_list>

struct Cell
{
    int x;
    int y;

    Cell() = default;
    Cell(int a, int b): x(a), y(b) {}

    bool operator <(const Cell &cell) const
    {
        if (x == cell.x)
        {
            return y < cell.y;
        }
        else
        {
            return x < cell.x;
        }
    }
};

std::ostream &operator<<(std::ostream &os, const Cell &cell)
{
    os << "{" << cell.x << "," << cell.y << "}";
    return os;
}

struct SCompare
{
    //自定义比较函数,重载“()”操作符
    bool operator()(const Cell & cell1, const Cell & cell2) const
    {
        return cell1 < cell2;
    }
};

int main()
{
    std::set<Cell, SCompare> set1;
    std::map<Cell, Cell, SCompare> map1;
    std::multiset<Cell, SCompare> multiset1;
    std::multimap<Cell, Cell, SCompare> multimap1;
    std::priority_queue<Cell, std::vector<Cell>, SCompare> priority_queue1;

    auto FCompare = [](const Cell & cell1, const Cell & cell2)
    {
        return cell1 < cell2;
    };

    std::vector<Cell> vector1;
    std::sort(vector1.begin(), vector1.end(), FCompare);
    std::forward_list<Cell> forward_list1;
    forward_list1.sort(FCompare);

    std::stable_sort(vector1.begin(), vector1.end(), FCompare);

    std::vector<Cell> vector2;
    std::partial_sort(vector1.begin(), vector1.end(), vector2.begin(), FCompare);
    std::partial_sort_copy(vector1.begin(), vector1.end(), vector2.begin(), vector2.end(), FCompare);
    std::is_sorted(vector1.begin(), vector1.end(), FCompare);
    std::is_sorted_until(vector1.begin(), vector1.end(), FCompare);

    std::nth_element(vector1.begin(), vector1.end(), vector2.begin(), FCompare);

    std::lower_bound(vector1.begin(), vector1.end(), *(vector1.begin() + 3), FCompare);
    std::upper_bound(vector1.begin(), vector1.end(), *(vector1.begin() + 3), FCompare);

    std::binary_search(vector1.begin(), vector1.end(), *(vector1.begin() + 3), FCompare);
    std::equal_range(vector1.begin(), vector1.end(), *(vector1.begin() + 3), FCompare);

    std::vector<Cell> vector3;
    std::merge(vector1.begin(), vector1.end(), vector2.begin(),
               vector2.end(), vector3.begin(), FCompare);
    std::forward_list<Cell> forward_list2;
    forward_list1.merge(forward_list2, FCompare);
    std::inplace_merge(vector1.begin(), vector1.end(), vector2.begin(), FCompare);

    std::includes(vector1.begin(), vector1.end(), vector2.begin(), vector2.end(), FCompare);

    std::set_difference(vector1.begin(), vector1.end(), vector2.begin(),
                        vector2.end(), vector3.begin(), FCompare);
    std::set_intersection(vector1.begin(), vector1.end(), vector2.begin(),
                          vector2.end(), vector3.begin(), FCompare);
    std::set_symmetric_difference(vector1.begin(), vector1.end(), vector2.begin(),
                                  vector2.end(), vector3.begin(), FCompare);
    std::set_union(vector1.begin(), vector1.end(), vector2.begin(),
                   vector2.end(), vector3.begin(), FCompare);

    std::max(Cell(), Cell(), FCompare);
    std::max_element(vector1.begin(), vector1.end(), FCompare);
    std::min(Cell(), Cell(), FCompare);
    std::min_element(vector1.begin(), vector1.end(), FCompare);
    std::minmax(Cell(), Cell(), FCompare);
    std::minmax_element(vector1.begin(), vector1.end(), FCompare);

    return 0;
}

文章来源:https://blog.csdn.net/qq_40788199/article/details/135563937
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。