理解C++谓词(断言函数)

目录

1.  什么是谓词(断言函数)(predicate)?

2.  几个断言函数的定义

3.  用法示例


1.  什么是谓词(断言函数)(predicate)?

         一直以来,很多书都翻译成“谓词”,是因为英语中对应的单词是“predicate”。但将这个称为“谓词”却很容易搞混淆,更准确地应称为“断言函数”

         断言要求描述一个返回 BooleanTestable 值的可调用函数。BooleanTestable指定这种类型和值类别的表达式可转换为 bool 类型,并且该类型或两个不同 BooleanTestable 类型的逻辑运算符具有通常的行为。其本质是将这种简单重复判断的工作交给模板通用模块去处理,传递函数地址以方便通用模块内部调用逻辑判断函数,即将遍历对比任务交给通用板块。

         断言通常用于接受输入数据(单个对象/容器)和断言的算法,然后对输入数据调用断言来决定进一步的操作。C++ 标准库中的一些断言用法的例子有:

std::all_ofstd::any_ofstd::none_of 将元素数组和断言作为输入。对各个输入元素调用断言函数,如果对于所有/任何/无元素,断言算法返回 true,则断言函数返回 true

std::find_if 取元素序列和断言。返回序列中断言返回值等于 true 的第一个元素。

2.  几个断言函数的定义

    几个断言函数其实是作为模板函数定义的:

定义于头文件 <algorithm>

template< class InputIt, class UnaryPred >
bool all_of( InputIt first, InputIt last, UnaryPred p );

(1)

(since C++11)
(constexpr since C++20)

template< class ExecutionPolicy, class ForwardIt, class UnaryPred >

bool all_of( ExecutionPolicy&& policy,

             ForwardIt first, ForwardIt last, UnaryPred p );

(2)

(since C++17)

template< class InputIt, class UnaryPred >
bool any_of( InputIt first, InputIt last, UnaryPred p );

(3)

(since C++11)
(constexpr since C++20)

template< class ExecutionPolicy, class ForwardIt, class UnaryPred >

bool any_of( ExecutionPolicy&& policy,

             ForwardIt first, ForwardIt last, UnaryPred p );

(4)

(since C++17)

template< class InputIt, class UnaryPred >
bool none_of( InputIt first, InputIt last, UnaryPred p );

(5)

(since C++11)
(constexpr since C++20)

template< class ExecutionPolicy, class ForwardIt, class UnaryPred >

bool none_of( ExecutionPolicy&& policy,

              ForwardIt first, ForwardIt last, UnaryPred p );

(6)

(since C++17)

(1) 检查一元谓词 p 是否对范围 [first, last) 中的至少一个元素返回 false

(3) 检查一元谓词 p 是否对范围 [first, last) 中的至少一个元素返回 true

(5) 检查一元谓词 p 是否对范围 [first, last) 中的任何元素均不返回 true

(2,4,6) 与 (1,3,5) 相同,但根据策略执行。

仅当满足以下所有条件时,这些重载才会参与重载决议:

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>  true.

(until C++20)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>  true.

(since C++20)

参数说明:

first last —— 定义要检查的元素之范围的成对迭代器。

Policy —— 执行检查的执行策略。

P —— 一元谓词(实际上是带一个参数的函数,返回值是bool ,实际调用时传函数地址)

对于每一个类型为VT(可能是const)的参数v (其中 VT InputIt 值类型(ValueType),与值类别无关,并且不能修改 v)表达式 p(v) 必须能够转换为 bool。因此,不允许使用 VT& 的参数类型,也不允许使用 VT,除非对于 VT 来说,移动等同于复制(自 C++11 起)。

类型要求:

InputIt 必须满足 LegacyInputIterator 的要求。

ForwardIt 必须满足 LegacyForwardIterator 的要求。

UnaryPred 必须满足 Predicate 的要求。

3.  用法示例

例1

#include <algorithm>

#include <functional>

#include <iostream>

#include <iterator>

#include <numeric>

#include <vector>

 int main()

{

    std::vector<int> v(10, 2);

    std::partial_sum(v.cbegin(), v.cend(), v.begin());

    std::cout << "Among the numbers: ";

    std::copy(v.cbegin(), v.cend(), std::ostream_iterator<int>(std::cout, " "));

    std::cout << '\n';

     if (std::all_of(v.cbegin(), v.cend(), [](int i) { return i % 2 == 0; }))

        std::cout << "All numbers are even\n";

     if (std::none_of(v.cbegin(), v.cend(), std::bind(std::modulus<>(),

                                                     std::placeholders::_1, 2)))

        std::cout << "None of them are odd\n";

     struct DivisibleBy

    {

        const int d;

        DivisibleBy(int n) : d(n) {}

        bool operator()(int n) const { return n % d == 0; }

    };

     if (std::any_of(v.cbegin(), v.cend(), DivisibleBy(7)))

        std::cout << "At least one number is divisible by 7\n";

}

输出:

Among the numbers: 2 4 6 8 10 12 14 16 18 20

All numbers are even

None of them are odd

At least one number is divisible by 7

例2:

#include <iostream>

#include <vector>

#include <algorithm>

using namespace std;

bool is_even(int n) {

   return (n % 2 == 0);

}

int main(void) {

   vector<int> v = {2, 4, 6, 8, 10};

   bool result;

   result = all_of(v.begin(), v.end(), is_even);

   if (result == true)

      cout << "Vector contains all even numbers." << endl;

   v[0] = 1;

   result = all_of(v.begin(), v.end(), is_even);

   if (result == false)

      cout << "Vector doesn't contain all even numbers." << endl;

   return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值