简介

  • C++ 标准库

引用包装器 std::ref

  • 我们经常需要处理各种各样的对象和函数调用,其中一个常见的问题是如何高效地传递对象。如果不注意,很容易引入不必要的拷贝开销和性能损失

  • 什么是std::ref

    • std::ref是 C++11 标准库中的一个函数模板,用于生成一个引用包装器。引用包装器本质上是对一个对象的引用进行封装,使得在某些场景下能够更加方便的传递和使用引用。
    • 例如,在标准库的算法和多线程库中,经常需要传递引用,而std::ref可以帮助我们简化这一过程。

为什么需要引用包装器

  • 在C++中,函数传参时有几种常见方式,每种方式都有其使用的场景和特点
    • 按值传递: 会创建参数对象的副本,可能带来额外的性能开销
    • 按指针传递:需要显式的处理指针,可能导致代码复杂性增加
    • 按引用传递:无需创建副本,性能较高,但是在某些场景下使用起来不够方便
  • 在需要保持对象的引用关系,但是又不想显示地使用指针或者引用时,引用包装器 std::ref 就派上用场了

如何使用std::ref

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <functional> // 引入std::ref

void increment(int& n) {
    ++n;
}

void call_increment() {
    int x = 5;
    std::function<void()> f = std::bind(increment, std::ref(x));
    f();
    std::cout << "x after increment: " << x << std::endl; // 输出:x after increment: 6
}

int main() {
    call_increment();
    return 0;
}
  • 在这个例子中,std::bind用于绑定函数increment和参数x,而std::ref确保传递的是x的引用,而不是副本。

std::ref在多线程中的应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
#include <thread>
#include <vector>
#include <functional>

void add_to_counter(int& counter, int num_iterations) {
    for (int i = 0; i < num_iterations; ++i) {
        ++counter;
    }
}

int main() {
    int counter = 0;
    int num_threads = 10;
    int num_iterations = 1000;
    std::vector<std::thread> threads;

    for (int i = 0; i < num_threads; ++i) {
        threads.emplace_back(add_to_counter, std::ref(counter), num_iterations);
    }

    for (auto& t : threads) {
        t.join();
    }

    std::cout << "Final counter value: " << counter << std::endl; // 输出:Final counter value: 10000
    return 0;
}
  • 在这个例子中,我们创建了10个线程,每个线程对同一个counter变量进行了1000次累加 操作。通过使用std::ref,我们确保每个线程操作的是同一个counter引用,而不是副本。

std::ref 与 std::cref

  • 除了 std::ref,C++标准库还提供了 std::cref,用于生成常量引用的包装器。
  • std::cref的使用方式与std::ref类似,不同之处在于它生成的是const引用,确保被引用的对象在使用过程中不会被修改。 ```cpp

#include #include

void print_value(const int& n) { std::cout « “Value: “ « n « std::endl; }

int main() { int x = 5; std::function<void()> f = std::bind(print_value, std::cref(x)); f(); // 输出:Value: 5 return 0; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
+ 在这个例子中,std::cref确保传递的是x的常量引用,print_value函数无法修改x的值。

### std::ref的内部实现

+ 虽然我们平时使用std::ref时只需要调用它的接口,但了解其内部实现有助于我们更深入地理解它的工作原理。std::ref的内部实现实际上非常简单,它定义了一个模板类reference_wrapper,用于封装引用。下面是一个简化的实现版本:
```cpp

template <typename T>
class reference_wrapper {
public:
    explicit reference_wrapper(T& ref) : ref_(std::addressof(ref)) {}

    operator T&() const { return *ref_; }

    T& get() const { return *ref_; }

private:
    T* ref_;
};

template <typename T>
reference_wrapper<T> ref(T& t) {
    return reference_wrapper<T>(t);
}
  • 可以看出,reference_wrapper通过保存一个指向引用对象的指针,实现了对引用的包装。
  • std::ref函数只是创建了一个reference_wrapper对象并且返回。

std::ref 小结

  • std::ref 作为C++标准库中的一个小工具,虽然看似简单,但是在实际编程中却能够解决很多复杂的问题。
  • 它不仅能够简化函数参数传递,还能在多线程编程中确保引用的正确传递,从而提升代码的性能和可读性。

什么是 std::function

  • std::function 是C++11引入的一个函数包装器类型。它的主要作用是,将任何可调用实体(比如函数,lambda表达式,函数指针或者函数对象)都包装成一个统一的对象,从而可以统一的保存,传递和调用这些可调用实体。
  • 简单的说,std::function就是一个可以容纳各种可调用实体的容器。我们可以将它看作是一个通用的函数指针,但是它比普通的函数指针更加灵活和强大。

  • std::function 提供了一种非常灵活和通用的方式来处理可调用实体,包括普通函数,lambda表达式以及函数对象。
  • 它的主要优点包括
    • 统一的函数调用接口,简化了代码
    • 可以存储在容器中,增强了代码的可扩展性
    • 可以与std::bind()结合使用,实现参数绑定等高级功能

C++ 标准库

<functional> 标准库是 C++ 中的一个头文件,提供了函数对象(Function Object)的支持,包括了一些预定义的函数对象和函数适配器。它使得函数能够像对象一样被传递、存储、返回以及调用。

这个库中的重要组件包括:

1. 函数对象(Function Objects)

函数对象是可以像函数一样被调用的对象。在 <functional> 中有一些内置的函数对象,如:

  • std::function:用于封装可调用的目标,可以是函数指针、函数、成员函数、Lambda 表达式等,是一种通用的函数封装器。
  • std::bind:用于创建函数对象,可绑定函数或者成员函数到指定的参数上。
  • std::placeholders:用于占位符,在使用 std::bind 绑定函数时,指定部分参数留待后续提供。

2. 函数适配器(Function Adapters)

函数适配器是用来修改函数行为的对象。常见的函数适配器有:

  • std::bind:上述已提到,可用于部分参数绑定和函数重组。
  • std::placeholders:占位符,用于 std::bind 中占位某些参数的位置。
  • std::function:用于封装可调用对象,提供了一种统一的处理方式。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <functional>

// Function object example
struct AddFunctor {
    int operator()(int a, int b) const {
        return a + b;
    }
};

int main() {
    // Using std::function with a lambda function
    std::function<int(int, int)> addFunction = [](int a, int b) {
        return a + b;
    };

    // Using std::bind to bind the first argument to 10
    auto addTen = std::bind(addFunction, 10, std::placeholders::_1);

    // Using a function object
    AddFunctor addObj;

    // Using the function object
    std::cout << "Result of addObj: " << addObj(5, 3) << std::endl;

    // Using std::function with std::bind
    std::cout << "Result of addFunction: " << addFunction(5, 3) << std::endl;

    // Using std::bind function to add 10
    std::cout << "Result of addTen: " << addTen(5) << std::endl;

    return 0;
}

这个示例展示了如何使用 <functional> 标准库中的函数对象和函数适配器。std::functionstd::bind 是这个库中常用的工具,它们提供了更灵活和通用的函数操作方式。

C++ 标准库 详解

<functional> 标准库是 C++ 中提供函数对象(Function Objects)和函数适配器(Function Adapters)的头文件。这个库提供了许多功能,能够让函数像对象一样进行操作、传递和存储,以及改变函数的行为。

下面是 <functional> 标准库中一些重要的组件:

1. 函数对象(Function Objects)

函数对象是具有函数调用功能的对象,它可以像函数一样被调用。在 <functional> 中提供了以下函数对象:

  • std::function:是一个通用的函数封装器,可以封装可调用的目标,例如函数指针、函数、成员函数、Lambda 表达式等。可以用来存储和调用各种类型的可调用对象。

  • 函数对象类:程序员可以自定义函数对象类,它们是类或结构体,重载了函数调用运算符 operator(),使得对象可以像函数一样被调用。

2. 函数适配器(Function Adapters)

函数适配器是用于修改函数行为或调整函数参数的对象。其中常见的函数适配器有:

  • std::bind:用于创建函数对象,可以部分绑定函数或成员函数的参数。可以改变函数的参数个数或者顺序。

  • std::placeholders:在使用 std::bind 绑定函数时,用于指定占位符,代表未指定的参数位置。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <functional>

// 函数对象示例
struct MultiplyFunctor {
    int operator()(int a, int b) const {
        return a * b;
    }
};

int main() {
    // 使用 std::function 包装 Lambda 表达式
    std::function<int(int, int)> multiplyFunction = [](int a, int b) {
        return a * b;
    };

    // 使用 std::bind 部分绑定参数
    auto multiplyByTwo = std::bind(multiplyFunction, std::placeholders::_1, 2);

    // 使用自定义函数对象
    MultiplyFunctor multiplyObj;

    // 使用自定义函数对象
    std::cout << "Result of multiplyObj: " << multiplyObj(5, 3) << std::endl;

    // 使用 std::function 调用 Lambda 函数
    std::cout << "Result of multiplyFunction: " << multiplyFunction(5, 3) << std::endl;

    // 使用 std::bind 绑定函数的参数
    std::cout << "Result of multiplyByTwo: " << multiplyByTwo(5) << std::endl;

    return 0;
}

这个示例演示了如何使用 <functional> 标准库中的函数对象和函数适配器。std::function 提供了一种通用的函数封装器,std::bind 则用于创建函数对象并部分绑定参数。函数对象可以是 Lambda 表达式、函数指针或自定义的函数对象类。

C++ 标准库 常用类和函数

<functional> 标准库提供了许多有用的类和函数,使得函数能够像对象一样进行操作、传递和存储。以下是 <functional> 常用的类和函数:

1. 类

std::function

  • 用于封装各种可调用对象,如函数指针、函数、成员函数、Lambda 表达式等。
  • 提供了一种通用的函数封装器,能够在运行时存储和调用各种类型的可调用对象。

std::bind

  • 用于创建函数对象,能够绑定函数或成员函数的参数。
  • 允许指定参数的顺序、部分绑定参数或者重新组织参数,生成一个新的可调用对象。

std::placeholders

  • 用于指定占位符,配合 std::bind 使用,指定未指定的参数位置。
  • 提供了占位符 _1_2_3 等,用于表示绑定时未指定的参数位置。

2. 函数

算术函数:

  • std::plus:加法函数对象。
  • std::minus:减法函数对象。
  • std::multiplies:乘法函数对象。
  • std::divides:除法函数对象。
  • std::modulus:取模函数对象。

逻辑函数:

  • std::logical_and:逻辑与函数对象。
  • std::logical_or:逻辑或函数对象。
  • std::logical_not:逻辑非函数对象。

其他函数:

  • std::negate:一元取反函数对象。
  • std::not1:一元谓词取反函数对象。
  • std::not2:二元谓词取反函数对象。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <functional>

// 函数对象示例
struct MultiplyFunctor {
    int operator()(int a, int b) const {
        return a * b;
    }
};

int main() {
    // 使用 std::function 封装 Lambda 表达式
    std::function<int(int, int)> multiplyFunction = [](int a, int b) {
        return a * b;
    };

    // 使用 std::bind 绑定函数对象并部分绑定参数
    auto multiplyByTwo = std::bind(multiplyFunction, std::placeholders::_1, 2);

    // 使用自定义函数对象
    MultiplyFunctor multiplyObj;

    // 使用自定义函数对象
    std::cout << "Result of multiplyObj: " << multiplyObj(5, 3) << std::endl;

    // 使用 std::function 调用 Lambda 函数
    std::cout << "Result of multiplyFunction: " << multiplyFunction(5, 3) << std::endl;

    // 使用 std::bind 绑定函数对象的参数
    std::cout << "Result of multiplyByTwo: " << multiplyByTwo(5) << std::endl;

    return 0;
}

这个示例展示了 <functional> 标准库中的一些常用函数和类的用法。std::function 可用于封装不同类型的可调用对象,std::bind 可用于创建函数对象并部分绑定参数,而函数对象可以是 Lambda 表达式、函数指针或自定义的函数对象类。

std::function

std::function<functional> 头文件中提供的一个类模板,用于封装可调用对象(函数、函数指针、成员函数、Lambda 表达式等),并提供一种通用的函数封装器。

基本语法:

1
2
3
#include <functional>

std::function<return_type(args...)> func_object;
  • return_type:函数或可调用对象返回类型。
  • args...:函数或可调用对象的参数类型列表。

特点和用途:

  • std::function 能够封装各种类型的可调用对象,提供了一种统一的处理方式。
  • 可以在运行时动态地指定要调用的函数或对象,从而实现动态多态性。
  • 可用作函数参数、返回值或容器内的元素类型,能够实现灵活的函数传递和存储。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <functional>

// 函数示例
int add(int a, int b) {
    return a + b;
}

int main() {
    // 封装普通函数
    std::function<int(int, int)> func = add;

    // 封装 Lambda 表达式
    std::function<int(int, int)> lambdaFunc = [](int x, int y) {
        return x * y;
    };

    // 调用封装的普通函数
    std::cout << "Result of add function: " << func(3, 4) << std::endl;

    // 调用封装的 Lambda 表达式
    std::cout << "Result of lambda function: " << lambdaFunc(3, 4) << std::endl;

    return 0;
}

在这个示例中,std::function 分别封装了一个普通函数和一个 Lambda 表达式,并能够像函数一样调用这些封装的对象。std::function 提供了一种通用的函数封装器,能够灵活地封装各种可调用对象,并统一地调用它们。

std::bind

std::bind<functional> 头文件中提供的一个函数模板,用于创建函数对象并进行参数绑定。

基本语法:

1
2
3
#include <functional>

auto func = std::bind(func_to_bind, args...);
  • func_to_bind:要绑定的函数、函数指针、成员函数指针或可调用对象。
  • args...:要绑定的参数列表,可以包含占位符 _1, _2, _3 等,代表未指定的参数位置。

特点和用途:

  • std::bind 允许对函数或函数对象进行部分参数绑定、参数重排以及参数固定等操作,生成一个新的函数对象。
  • 可以用来创建函数对象,将部分参数预先绑定,使得函数调用更加灵活。
  • 创建了一个新的可调用对象,其参数列表为绑定参数后剩余的参数。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <functional>

// 函数示例
int add(int a, int b) {
    return a + b;
}

int main() {
    // 绑定参数的 add 函数
    auto addFive = std::bind(add, 5, std::placeholders::_1);

    // 调用绑定参数的 add 函数
    std::cout << "Result of addFive function: " << addFive(3) << std::endl;

    return 0;
}

在这个示例中,std::bind 绑定了一个参数为 5 的 add 函数,并将第二个参数作为占位符 _1 留待后续提供。之后创建了一个新的函数对象 addFive,用于调用绑定了部分参数的 add 函数。std::bind 允许对函数进行部分参数绑定,生成一个新的可调用对象。

std::placeholders

std::placeholders<functional> 头文件中的一个命名空间,其中定义了一系列占位符,用于在使用 std::bind 时指示参数的位置。

常用的占位符:

  • _1_2_3_n:表示函数调用时的第一个、第二个、第三个… 第n个参数位置。

这些占位符用于 std::bind 中,协助进行参数绑定。在 std::bind 中,使用这些占位符可以指定哪些参数是预先绑定的,哪些参数需要在调用时提供。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <functional>

void printThree(int a, int b, int c) {
    std::cout << a << ", " << b << ", " << c << std::endl;
}

int main() {
    // 绑定函数并重新排列参数顺序
    auto printFunction = std::bind(printThree, std::placeholders::_3, std::placeholders::_1, std::placeholders::_2);

    // 调用绑定函数
    printFunction(1, 2, 3);

    return 0;
}

在这个示例中,std::placeholders 的占位符 _1_2_3 分别表示绑定的函数 printThree 的第三个、第一个和第二个参数的位置。std::bind 创建了一个新的函数对象 printFunction,并重新排列了参数顺序。在调用 printFunction 时,参数的顺序将被重新排列以匹配绑定的函数。

std::plus

std::plus<functional> 头文件中提供的函数对象,用于执行加法操作。它是一个函数对象类,重载了函数调用运算符 operator(),使其能够执行加法操作。

基本语法:

1
2
3
#include <functional>

std::plus<T> plus_object;
  • T:加法操作的参数类型。

使用方法:

std::plus 对象可以像函数一样调用,用于执行加法操作。它是一个模板类,可以根据需要指定不同的参数类型,比如 intfloatdouble 等。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <functional>

int main() {
    std::plus<int> plusInt;

    int result = plusInt(3, 4); // 执行加法操作

    std::cout << "Result of addition: " << result << std::endl;

    return 0;
}

在这个示例中,std::plus 实例化为 std::plus<int>,表示执行整数类型的加法操作。plusInt 对象被调用并传递两个参数,执行加法操作并返回结果。

std::minus

std::minus<functional> 头文件中提供的函数对象,用于执行减法操作。它也是一个函数对象类,重载了函数调用运算符 operator(),使其能够执行减法操作。

基本语法:

1
2
3
#include <functional>

std::minus<T> minus_object;
  • T:减法操作的参数类型。

使用方法:

std::minus 对象可以像函数一样调用,用于执行减法操作。它是一个模板类,可以根据需要指定不同的参数类型,比如 intfloatdouble 等。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <functional>

int main() {
    std::minus<int> minusInt;

    int result = minusInt(7, 4); // 执行减法操作

    std::cout << "Result of subtraction: " << result << std::endl;

    return 0;
}

在这个示例中,std::minus 实例化为 std::minus<int>,表示执行整数类型的减法操作。minusInt 对象被调用并传递两个参数,执行减法操作并返回结果。

std::multiplies

std::multiplies<functional> 头文件中提供的函数对象,用于执行乘法操作。它是一个函数对象类,重载了函数调用运算符 operator(),使其能够执行乘法操作。

基本语法:

1
2
3
#include <functional>

std::multiplies<T> multiplies_object;
  • T:乘法操作的参数类型。

使用方法:

std::multiplies 对象可以像函数一样调用,用于执行乘法操作。它是一个模板类,可以根据需要指定不同的参数类型,比如 intfloatdouble 等。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <functional>

int main() {
    std::multiplies<int> multipliesInt;

    int result = multipliesInt(3, 4); // 执行乘法操作

    std::cout << "Result of multiplication: " << result << std::endl;

    return 0;
}

在这个示例中,std::multiplies 实例化为 std::multiplies<int>,表示执行整数类型的乘法操作。multipliesInt 对象被调用并传递两个参数,执行乘法操作并返回结果。

std::divides

std::divides<functional> 头文件中提供的函数对象,用于执行除法操作。它是一个函数对象类,重载了函数调用运算符 operator(),使其能够执行除法操作。

基本语法:

1
2
3
#include <functional>

std::divides<T> divides_object;
  • T:除法操作的参数类型。

使用方法:

std::divides 对象可以像函数一样调用,用于执行除法操作。它是一个模板类,可以根据需要指定不同的参数类型,比如 intfloatdouble 等。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <functional>

int main() {
    std::divides<double> dividesDouble;

    double result = dividesDouble(10.0, 2.0); // 执行除法操作

    std::cout << "Result of division: " << result << std::endl;

    return 0;
}

在这个示例中,std::divides 实例化为 std::divides<double>,表示执行双精度浮点数类型的除法操作。dividesDouble 对象被调用并传递两个参数,执行除法操作并返回结果。

std::modulus

std::modulus<functional> 头文件中提供的函数对象,用于执行取模(取余)操作。它是一个函数对象类,重载了函数调用运算符 operator(),使其能够执行取模操作。

基本语法:

1
2
3
#include <functional>

std::modulus<T> modulus_object;
  • T:取模操作的参数类型。

使用方法:

std::modulus 对象可以像函数一样调用,用于执行取模操作。它是一个模板类,可以根据需要指定不同的参数类型,比如 intfloatdouble 等。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <functional>

int main() {
    std::modulus<int> modulusInt;

    int result = modulusInt(10, 3); // 执行取模操作

    std::cout << "Result of modulus: " << result << std::endl;

    return 0;
}

在这个示例中,std::modulus 实例化为 std::modulus<int>,表示执行整数类型的取模操作。modulusInt 对象被调用并传递两个参数,执行取模操作并返回结果。

std::logical_and

std::logical_and<functional> 头文件中提供的函数对象,用于执行逻辑与操作。它是一个函数对象类,重载了函数调用运算符 operator(),使其能够执行逻辑与操作。

基本语法:

1
2
3
#include <functional>

std::logical_and<T> logical_and_object;
  • T:逻辑与操作的参数类型。

使用方法:

std::logical_and 对象可以像函数一样调用,用于执行逻辑与操作。它是一个模板类,可以根据需要指定不同的参数类型,比如 bool 等。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <functional>

int main() {
    std::logical_and<bool> logicalAndBool;

    bool result = logicalAndBool(true, false); // 执行逻辑与操作

    std::cout << "Result of logical AND: " << std::boolalpha << result << std::endl;

    return 0;
}

在这个示例中,std::logical_and 实例化为 std::logical_and<bool>,表示执行布尔类型的逻辑与操作。logicalAndBool 对象被调用并传递两个参数,执行逻辑与操作并返回结果。

std::logical_or

std::logical_or<functional> 头文件中提供的函数对象,用于执行逻辑或操作。它是一个函数对象类,重载了函数调用运算符 operator(),使其能够执行逻辑或操作。

基本语法:

1
2
3
#include <functional>

std::logical_or<T> logical_or_object;
  • T:逻辑或操作的参数类型。

使用方法:

std::logical_or 对象可以像函数一样调用,用于执行逻辑或操作。它是一个模板类,可以根据需要指定不同的参数类型,比如 bool 等。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <functional>

int main() {
    std::logical_or<bool> logicalOrBool;

    bool result = logicalOrBool(true, false); // 执行逻辑或操作

    std::cout << "Result of logical OR: " << std::boolalpha << result << std::endl;

    return 0;
}

在这个示例中,std::logical_or 实例化为 std::logical_or<bool>,表示执行布尔类型的逻辑或操作。logicalOrBool 对象被调用并传递两个参数,执行逻辑或操作并返回结果。

std::logical_not

std::logical_not<functional> 头文件中提供的函数对象,用于执行逻辑非(取反)操作。它是一个函数对象类,重载了函数调用运算符 operator(),使其能够执行逻辑非操作。

基本语法:

1
2
3
#include <functional>

std::logical_not<T> logical_not_object;
  • T:逻辑非操作的参数类型。

使用方法:

std::logical_not 对象可以像函数一样调用,用于执行逻辑非操作。它是一个模板类,可以根据需要指定不同的参数类型,比如 bool 等。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <functional>

int main() {
    std::logical_not<bool> logicalNotBool;

    bool result = logicalNotBool(true); // 执行逻辑非操作

    std::cout << "Result of logical NOT: " << std::boolalpha << result << std::endl;

    return 0;
}

在这个示例中,std::logical_not 实例化为 std::logical_not<bool>,表示执行布尔类型的逻辑非操作。logicalNotBool 对象被调用并传递一个参数,执行逻辑非操作并返回结果。

std::negate

std::negate<functional> 头文件中提供的函数对象,用于执行一元取反操作。它是一个函数对象类,重载了函数调用运算符 operator(),使其能够执行一元取反操作。

基本语法:

1
2
3
#include <functional>

std::negate<T> negate_object;
  • T:取反操作的参数类型。

使用方法:

std::negate 对象可以像函数一样调用,用于执行一元取反操作。它是一个模板类,可以根据需要指定不同的参数类型,比如 intfloatdouble 等。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <functional>

int main() {
    std::negate<int> negateInt;

    int result = negateInt(10); // 执行一元取反操作

    std::cout << "Result of unary negation: " << result << std::endl;

    return 0;
}

在这个示例中,std::negate 实例化为 std::negate<int>,表示执行整数类型的一元取反操作。negateInt 对象被调用并传递一个参数,执行一元取反操作并返回结果。

std::not1

std::not1<functional> 头文件中提供的函数对象适配器,用于对一元谓词函数进行取反操作。它可用于构造一个函数对象,将传入的一元谓词函数对象的结果进行取反。

基本语法:

1
2
3
#include <functional>

std::not1<UnaryPredicate> not1_object;
  • UnaryPredicate:一元谓词函数对象类型。

使用方法:

std::not1 可以用于对一元谓词函数对象进行取反操作。它接受一个一元谓词函数对象作为参数,并返回一个新的谓词函数对象,该对象对传入的谓词函数的返回值进行取反。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <functional>

bool greaterThanThree(int x) {
    return x > 3;
}

int main() {
    std::function<bool(int)> pred = std::not1<std::function<bool(int)>>(greaterThanThree);

    std::cout << "Result of not1: " << std::boolalpha << pred(4) << std::endl; // Result will be false

    return 0;
}

在这个示例中,std::not1greaterThanThree 函数对象进行取反操作。pred 对象被调用并传递一个参数,返回结果为传入参数的一元谓词函数的取反结果。

std::not2

std::not2<functional> 头文件中提供的函数对象适配器,用于对二元谓词函数进行取反操作。它可用于构造一个函数对象,将传入的二元谓词函数对象的结果进行取反。

基本语法:

1
2
3
#include <functional>

std::not2<BinaryPredicate> not2_object;
  • BinaryPredicate:二元谓词函数对象类型。

使用方法:

std::not2 可以用于对二元谓词函数对象进行取反操作。它接受一个二元谓词函数对象作为参数,并返回一个新的谓词函数对象,该对象对传入的谓词函数的返回值进行取反。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <functional>

bool lessThanOrEqual(int x, int y) {
    return x <= y;
}

int main() {
    std::function<bool(int, int)> pred = std::not2<std::function<bool(int, int)>>(lessThanOrEqual);

    std::cout << "Result of not2: " << std::boolalpha << pred(4, 3) << std::endl; // Result will be false

    return 0;
}

在这个示例中,std::not2lessThanOrEqual 函数对象进行取反操作。pred 对象被调用并传递两个参数,返回结果为传入参数的二元谓词函数的取反结果。