std::function 和 std::bind 特性都是属于<functional>头文件中; std::forward 特性属于<utility>头文件中;
一、std::function 特性介绍
类模板std::function是一种通用、多态的函数封装。std::function的实例可以对任何可以调用的目标实体进行存储、复制和调用操作,这些目标实体包括普通函数、Lambda表达式、函数指针以及其它函数对象等。std::function对象是对C++中现有的可调用实体的一种类型安全的包裹(std::function就是对标函数指针类型不安全的可调用实体而实现的)。
封装普通函数例子
#ifndef TEST_H
#define TEST_H
#include <iostream>
#include <functional>
int add(int a, int b);
#endif
#include "test.h"
std::function<int(int, int)> func = add;
std::function<int(int, int)> func1 = [](int a, int b) {return a+b;};
int main()
{
std::cout << "func(1, 2): " << func(1, 2) << std::endl;
std::cout << "func1(4, 5): " << func1(4, 5) << std::endl;
return 0;
}#endif
封装仿函数例子
#ifndef TEST_H
#define TEST_H
#include <iostream>
#include <functional>
typedef std::function<int(int)> Functornal;
class Functor{
public:
int operator()(int a) {
return a;
}
};
#endif
#include "test.h"
int main()
{
//1.1 fucntor
Functor func;
Functornal fobj = func;
int fres = fobj(3);
std::cout << "functor fres: " << fres << std::endl;
return 0;
}
封装类成员函数和类静态成员函数例子
#ifndef TEST_H
#define TEST_H
#include <iostream>
#include <functional>
typedef std::function<int(int, int)> Functional;
typedef std::function<const char*(const char*)> SFunctional;
class CTest{
public:
int Func(int a, int b) {
return a+b;
}
static const char *S_Func(const char* s) {
return s;
}
};
#endif
#include "test.h"
int main()
{
//1.2 bind
CTest t;
Functional obj = std::bind(&CTest::Func, &t, std::placeholders::_2, std::placeholders::_2);
int res = obj(3,5);
std::cout << "member function: " << res << std::endl;
//1.3 static bind
SFunctional sobj = std::bind(&CTest::S_Func, std::placeholders::_1);
const char* sres = sobj("nihao");
std::cout << "member function1: " << sres << std::endl;
//1.4 common function use
SFunctional sobj1 = CTest::S_Func;
const char* sres1 = sobj1("hello world.");
std::cout << "member function2: " << sres1 << std::endl;
return 0;
}
二、std::bind 特性介绍
std::bind 允许你创建一个可调用的函数对象,即一个“绑定”的函数,它将一个或者多个参数固定到一个可调用实体(函数、lambda表达式、函数对象等)的参数上。 使用std::bind,你可以:
- 固定参数:将一个参数值固定在函数调用中,使得后续调用时只需要提供剩余的参数;
- 延迟调用:创建一个调用的对象,该对象可以稍后被调用,此时它将使用固定的参数加上额外提供的参数;
- 适配器:std::bind 可用于适配函数,例如,将成员函数适配为可调用对象;
基本使用例子
#include <iostream>
#include <functional>
void greet(const std::string& who) {
std::cout << "Hello, " << who << "!" << std::endl;
}
int main() {
//绑定参数
auto bound_greet = std::bind(greet, "World");
//调用函数
bound_greet();
return 0;
}
std::bind 还可以与std::placeholders 一起使用,以占位符的形式提供参数,这样在调用时可以提供这些参数:
#include <iostream>
#include <functional>
int add(int a, int b) {
return a+b;
}
int main {
auto abound_add = std::bind(add, 10, std::placeholders::_1);
std::cout << bound_add(20) << std::endl;
return 0;
}
作为适配器的时候,通常和std::function 一起使用;
#include <iostream>
#include <functional>
int add(int a, int b) {
return a+b;
}
std::function<void(int, const std::string&)> func = std::bind(add, int a, const std::string& ch);
三、 std::forward特性介绍
std::forward 是一个C++ 中的一个模板函数,它用于在模板中以“转发”的方式传递参数。与std::move相比,std::move 将对象转换为右值引用,而std::forward 则保持对象的左值或者右值状态; std::forward 主要用于实现完美转发,这是C++ 中的一种技术,允许模板函数接受任意类型的参数,并将它们以原始的值类别(左值或者右值)转发给另外一个函数。完美转发在模板编程中非常重要,因为它允许调用者以期望的值类别传递参数。 使用std::forward的场景:
- 保持参数的值类别:当你在模板函数中需要将参数转发给另一个函数的时候,使用std::forward可以保持参数的原始值类别;
- 实现通用引用:在模板函数中,通用引用(也称为转发引用)可以绑定到左值或者右值;