当前位置: 首页 > news >正文

C++ 具名要求-全库范围的概念 -谓词(Predicate)-二元谓词(BinaryPredicate)

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

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

全库范围的概念

谓词

函数对象 (FunctionObject) ,对于一个实参,返回一个可转换为 bool 的值而不改动实参
C++ 具名要求: Predicate

谓词 (Predicate) 要求描述了返回可作为 bool 测试的值的可调用 (Callable) 体。

谓词 (Predicate) 常与接收输入数据(单独的对象/容器)和谓词的算法一起使用,它会针对输入数据进行调用以决定进一步的动作。C++ 标准库中的一些使用谓词的例子有:

  • std::all_of、std::any_of、std::none_of 接收一组元素和一个谓词为其输入。在每个单独的输入元素上调用谓词,并且当谓词分别对全部/任一/无元素返回 true 时返回 true。
  • std::find_if 接受元素的序列和一个谓词。返回序列中首个谓词对其返回 true 的元素。

上面给出的算法设施描述是简陋的,并且有意地简要解释谓词 (Predicate) 。对于详细信息可查阅各自的页面。

换言之,若算法接收一个谓词 (Predicate) pred 和一个迭代器 first,则它应该能经由类似 if(pred(*first)) {...} 的构造,测试迭代器 first 所指向的类型。

函数对象 pred 不应当通过解引用的迭代器运用任何非 const 函数。此函数对象可以是函数指针,或者拥有适合的函数调用运算符的类型的对象。

二元谓词

函数对象 (FunctionObject) ,对于两个实参,返回一个可转换为 bool 的值而不改动各实参
C++ 具名要求: BinaryPredicate

二元谓词 (BinaryPredicate) 是一些标准库设施针对用户提供的实参所期待的一组要求。

给定二元谓词 (BinaryPredicate) bin_pred 和一对迭代器 iter1iter2 或一个迭代器 iter 与值 value,表达式 bin_pred(*iter1, *iter2) 或 bin_pred(*iter, value) 必须可按语境转换为 bool。

另外,不允许表达式的求值调用解引用迭代器的非 const 成员函数。

要求

  • 谓词 (Predicate)
  • 可复制构造 (CopyConstructible) (除非另行指明)

标准库

下列标准库设施期待并非比较 (Compare) 类型的二元谓词 (BinaryPredicate)

unique

删除连续的重复元素
(std::forward_list<T,Allocator> 的公开成员函数)

unique

删除连续的重复元素
(std::list<T,Allocator> 的公开成员函数)

find_end

在特定范围中寻找最后出现的元素序列
(函数模板)

find_first_of

搜索元素集合中的任意元素
(函数模板)

adjacent_find

查找首对相邻的相同(或满足给定谓词的)元素
(函数模板)

mismatch

寻找两个范围出现不同的首个位置
(函数模板)

equal

确定两个元素集合是否是相同的
(函数模板)

is_permutation

(C++11)

判断一个序列是否为另一个序列的排列
(函数模板)

search

搜索一个元素范围
(函数模板)

search_n

在范围中搜索一定量的某个元素的连续副本
(函数模板)

unique

移除范围内的连续重复元素
(函数模板)

unique_copy

创建某范围的不含连续重复元素的副本
(函数模板)

not2

(C++17 中弃用)(C++20 中移除)

构造定制的 std::binary_negate 对象
(函数模板)

unordered_set

(C++11 起)

唯一键的集合,按照键生成散列
(类模板)

unordered_map

(C++11 起)

键值对的集合,按照键生成散列,键是唯一的
(类模板)

unordered_multiset

(C++11 起)

键的集合,按照键生成散列
(类模板)

unordered_multimap

(C++11 起)

键值对的集合,按照键生成散列
(类模板)

调用示例

 

#include <iostream>
#include <string>
#include <iterator>
#include <algorithm>
#include <functional>
#include <time.h>
#include <vector>struct Cell
{int x;int y;Cell() = default;Cell(int a, int b): x(a), y(b) {}Cell &operator +=(const Cell &cell){x += cell.x;y += cell.y;return *this;}Cell &operator +(const Cell &cell){x += cell.x;y += cell.y;return *this;}Cell &operator *(const Cell &cell){x *= cell.x;y *= cell.y;return *this;}Cell &operator ++(){x += 1;y += 1;return *this;}bool operator <(const Cell &cell) const{if (x == cell.x){return y < cell.y;}else{return x < cell.x;}}bool operator >(const Cell &cell) const{if (x == cell.x){return y > cell.y;}else{return x > cell.x;}}bool operator ==(const Cell &cell) const{return x == cell.x && y == cell.y;}
};std::ostream &operator<<(std::ostream &os, const Cell &cell)
{os << "{" << cell.x << "," << cell.y << "}";return os;
}int main()
{std::cout << std::boolalpha;std::vector<Cell> vector1{{101, 102}, {103, 104}, {105, 106}, {107, 108}};auto function1 = [](const Cell & cell){if (cell > Cell{105, 106}){return true;}return false;};std::cout << "std::all_of(  > Cell{105, 106}):    "<< std::all_of(vector1.begin(), vector1.end(), function1) << std::endl;std::cout << "std::any_of(  > Cell{105, 106}):    "<< std::any_of(vector1.begin(), vector1.end(), function1) << std::endl;std::cout << "std::none_of( > Cell{105, 106}):    "<< std::none_of(vector1.begin(), vector1.end(), function1) << std::endl;std::cout << std::endl;auto function2 = [](const Cell & cell1, const Cell & cell2){return cell1 == cell2;} ;std::vector<Cell> vector2 = vector1;vector2.push_back({107, 108});std::copy(vector2.cbegin(), vector2.cend(), std::ostream_iterator<Cell>(std::cout, " "));std::cout << std::endl;std::unique(vector2.begin(), vector2.end(), function2);std::cout << "after unique:" << std::endl;std::copy(vector2.cbegin(), vector2.cend(), std::ostream_iterator<Cell>(std::cout, " "));std::cout << std::endl;std::cout << "std::equal(vector1.begin(), vector1.end(), vector2.begin(), function2):   "<< std::equal(vector1.begin(), vector1.end(), vector2.begin(), function2);return 0;
}

输出

std::all_of(  > Cell{105, 106}):    false
std::any_of(  > Cell{105, 106}):    true
std::none_of( > Cell{105, 106}):    false{101,102} {103,104} {105,106} {107,108} {107,108}
after unique:
{101,102} {103,104} {105,106} {107,108} {107,108}
std::equal(vector1.begin(), vector1.end(), vector2.begin(), function2):   true

http://www.lryc.cn/news/280278.html

相关文章:

  • MyBatis-Plus不写任何resultMap和SQL执行一对一、一对多、多对多关联查询
  • arcgis javascript api4.x加载天地图web墨卡托(wkid:3857)坐标系
  • 中职组安全-win20230217-环境-解析
  • PMP学习考试经验总结
  • leetcode206.反转链表
  • python每日学17:控制推导逻辑的子表达式不要超过两个
  • 地质时间与数值模拟时间转换(mm/Ma-->m/s)
  • linux文件描述符管理
  • 谷歌翻译不能使用 host添加IP
  • Redis命令 - Lists命令组常用命令
  • 切分大文件sql为小份
  • 最新版CleanMyMac X4.14.7智能清理mac磁盘垃圾工具
  • 数据割据:当代社会数据治理的挑战
  • 逻辑回归(解决分类问题)
  • 论文阅读:Feature Refinement to Improve High Resolution Image Inpainting
  • 结构型设计模式——适配器模式
  • 三菱FX系列PLC定长切割控制(线缆裁切)
  • GPT编程:运行第一个聊天程序
  • NLP论文阅读记录 - WOS | ROUGE-SEM:使用ROUGE结合语义更好地评估摘要
  • vscode 创建文件自动添加注释信息
  • JVM内存区域详解,一文弄懂JVM内存【内存分布、回收算法、垃圾回收器】
  • uniapp搜索附近蓝牙信标(iBeacon)
  • Redis 常见数据结构以及使用场景分析
  • LMDeploy 大模型量化部署实践
  • 15个为你的品牌增加曝光的维基百科推广方法-华媒舍
  • 启动redis出现Creating Server TCP listening socket 127.0.0.1:6379: bind: No error异常
  • 响应式编程Reactor优化Callback回调地狱
  • React项目实战--------极客园项目PC端
  • Jerry每次能向前或向后走n*n步(始终不能超过初始位置1e5),q(q <= 1e5)次询问,求向前走d最少要几次
  • 【Spring Boot 3】【Flyway】数据库版本管理