std::function
std::function 是 C++ 标准库中定义在
主要特点
通用性:能够封装各种类型的可调用对象,无论是简单的函数指针,还是复杂的类成员函数,亦或是带有特定上下文环境的 Lambda 表达式等,都可以通过 std::function 来统一管理。
多态性:可以存储不同类型的可调用对象,调用时根据存储的对象类型自动进行相应的调用操作,无需用户手动处理不同类型的调用细节。
可复制性:支持复制操作,可以方便地将一个 std::function 对象复制给另一个,复制后的对象会共享相同的调用行为。
基本用法
定义和初始化
1空初始化
std::function<void()> func;
直接初始化 普通函数
void print_hello() { std::cout << "Hello" << std::endl; }
std::function<void()> func1 = print_hello;
Lambda 表达式
std::function<int(int, int)> func2 = [](int a, int b) { return a + b; };
绑定表达式
struct MyClass {void member_func(int x) { std::cout << x << std::endl; }
};
MyClass obj;
std::function<void(int)> func3 = std::bind(&MyClass::member_func, obj, std::placeholders::_1);
调用
func1(); // 调用 print_hello 函数
int sum = func2(3, 4); // 调用 Lambda 表达式,计算 3 + 4
func3(5); // 调用 MyClass 的成员函数 member_func,传入参数 5
检查是否为空
empty() 成员函数
if (func.empty()) {std::cout << "func is empty" << std::endl;
} else {std::cout << "func is not empty" << std::endl;
}
operator bool()if (func1) {std::cout << "func1 is not empty" << std::endl;
} else {std::cout << "func1 is empty" << std::endl;
}
获取目标类型和目标对象
target_type()if (func1.target_type() == typeid(void (*)())) {std::cout << "func1 targets a free function" << std::endl;
}
target()auto* lambda = func2.target< decltype([](int a, int b) { return a + b; })>();
if (lambda) {std::cout << "func2 targets a lambda expression" << std::endl;
}
应用场景
1 回调函数:在很多需要使用回调函数的场景中,std::function 可以方便地封装各种类型的回调函数,使得回调函数的使用更加灵活和通用。例如,在事件处理、异步编程等场景中,可以将不同类型的函数或对象作为回调函数传递给相应的处理函数或类。
2 算法参数:在使用标准库算法时,如果需要传递自定义的函数或函数对象作为算法的参数,std::function 可以提供一种方便的方式来封装这些参数,使得算法的使用更加灵活。
3 函数指针替代品:在一些原本需要使用函数指针的地方,使用 std::function 可以避免函数指针的一些限制,如无法直接封装成员函数、Lambda 表达式等,同时还能提供更强大的功能和更好的类型安全性。