跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
C++stdfunction
”︁
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
{{Note|本章节需要读者具备C++基础语法、函数指针和模板的基本知识。}} = C++ std::function = '''std::function''' 是C++11标准库中引入的通用函数包装器,属于<code><functional></code>头文件。它提供了一种类型安全的方式存储、复制和调用任何可调用对象(函数、lambda表达式、函数对象、绑定表达式等)。 == 基本概念 == std::function的核心特性: * 可以存储任何'''可调用目标(Callable Target)''',只要其签名与function的模板参数匹配 * 提供统一的调用接口<code>operator()</code> * 当不含可调用目标时,调用会抛出<code>std::bad_function_call</code>异常 * 是'''多态函数包装器''',运行时动态绑定具体实现 数学上可以表示为函数类型<math>F: A \rightarrow B</math>的包装器,其中A是参数类型,B是返回类型。 == 声明语法 == 基本声明格式: <syntaxhighlight lang="cpp"> #include <functional> std::function<return_type(parameter_types)> func_name; </syntaxhighlight> 示例声明: <syntaxhighlight lang="cpp"> std::function<int(int, int)> binary_op; // 包装返回int,接受两个int参数的函数 std::function<void()> callback; // 包装无参数无返回的函数 </syntaxhighlight> == 基础用法示例 == === 包装普通函数 === <syntaxhighlight lang="cpp"> #include <iostream> #include <functional> int add(int a, int b) { return a + b; } int main() { std::function<int(int, int)> func = add; std::cout << "Result: " << func(3, 4) << std::endl; // 输出: Result: 7 return 0; } </syntaxhighlight> === 包装Lambda表达式 === <syntaxhighlight lang="cpp"> #include <iostream> #include <functional> int main() { std::function<int(int)> square = [](int x) { return x * x; }; std::cout << "Square of 5: " << square(5) << std::endl; // 输出: Square of 5: 25 return 0; } </syntaxhighlight> === 包装函数对象 === <syntaxhighlight lang="cpp"> #include <iostream> #include <functional> struct Multiply { int operator()(int a, int b) const { return a * b; } }; int main() { std::function<int(int, int)> func = Multiply(); std::cout << "Product: " << func(3, 4) << std::endl; // 输出: Product: 12 return 0; } </syntaxhighlight> == 成员函数处理 == 包装成员函数需要结合<code>std::bind</code>或lambda表达式: <syntaxhighlight lang="cpp"> #include <iostream> #include <functional> class MyClass { public: int memberFunc(int x) { return x * 2; } }; int main() { MyClass obj; // 使用std::bind std::function<int(int)> func1 = std::bind(&MyClass::memberFunc, &obj, std::placeholders::_1); // 使用lambda std::function<int(int)> func2 = [&obj](int x) { return obj.memberFunc(x); }; std::cout << func1(5) << ", " << func2(5) << std::endl; // 输出: 10, 10 return 0; } </syntaxhighlight> == 状态检查 == 使用<code>operator bool()</code>检查是否包含有效目标: <syntaxhighlight lang="cpp"> #include <iostream> #include <functional> void checkFunction(const std::function<void()>& func) { if (func) { std::cout << "Function is callable" << std::endl; func(); } else { std::cout << "Function is empty" << std::endl; } } int main() { std::function<void()> emptyFunc; checkFunction(emptyFunc); // 输出: Function is empty emptyFunc = []{ std::cout << "Hello!" << std::endl; }; checkFunction(emptyFunc); // 输出: Function is callable 然后输出: Hello! return 0; } </syntaxhighlight> == 性能考虑 == std::function的实现通常使用'''类型擦除(Type Erasure)'''技术,这会带来一定的性能开销: <mermaid> flowchart TD A[调用std::function] --> B[虚函数表查找] B --> C[动态分配内存] C --> D[实际函数调用] </mermaid> 与直接函数调用相比,std::function的调用大约有2-3倍的性能下降。在性能关键路径上应考虑直接使用模板或函数指针。 == 实际应用案例 == === 回调机制 === 在事件驱动系统中广泛使用: <syntaxhighlight lang="cpp"> #include <iostream> #include <functional> #include <vector> class Button { std::function<void()> onClick; public: void setOnClick(const std::function<void()>& callback) { onClick = callback; } void click() { if (onClick) onClick(); } }; int main() { Button btn; btn.setOnClick([]() { std::cout << "Button clicked!" << std::endl; }); btn.click(); // 输出: Button clicked! return 0; } </syntaxhighlight> === 策略模式实现 === 运行时替换算法策略: <syntaxhighlight lang="cpp"> #include <iostream> #include <functional> #include <vector> class Sorter { std::function<void(std::vector<int>&)> strategy; public: void setStrategy(const std::function<void(std::vector<int>&)>& s) { strategy = s; } void sort(std::vector<int>& data) { if (strategy) strategy(data); } }; int main() { Sorter sorter; std::vector<int> data = {5, 2, 8, 1, 9}; // 设置冒泡排序策略 sorter.setStrategy([](std::vector<int>& v) { for (size_t i = 0; i < v.size(); ++i) for (size_t j = 0; j < v.size()-i-1; ++j) if (v[j] > v[j+1]) std::swap(v[j], v[j+1]); }); sorter.sort(data); for (int n : data) std::cout << n << " "; // 输出: 1 2 5 8 9 return 0; } </syntaxhighlight> == 与函数指针比较 == {| class="wikitable" |- ! 特性 !! std::function !! 函数指针 |- | 可调用类型 || 任何可调用对象 || 仅普通函数 |- | 捕获状态 || 可以 || 不可以 |- | 类型安全 || 是 || 是 |- | 性能 || 较低 || 较高 |- | 灵活性 || 高 || 低 |} == 常见问题 == === 为什么使用std::function而不是auto?=== * <code>auto</code>在编译时确定类型,无法存储在容器中或作为类成员 * std::function提供统一的类型接口,便于传递和存储 === 如何传递带捕获的lambda?=== 直接赋值即可,std::function会自动处理捕获状态: <syntaxhighlight lang="cpp"> int x = 10; std::function<int()> func = [x]() { return x * 2; }; </syntaxhighlight> == 总结 == std::function是C++中强大的函数包装器,它: * 提供统一的调用接口 * 支持多种可调用对象 * 实现类型安全的回调机制 * 在需要运行时多态性的场景特别有用 {{Warning|不要滥用std::function,在编译时能确定类型的场景应优先使用模板或auto。}} == 扩展阅读 == * C++标准库文档:std::function * 类型擦除技术 * 函数式编程概念 [[Category:编程语言]] [[Category:C++]] [[Category:C++stl 函数对象]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)
该页面使用的模板:
模板:Mbox
(
编辑
)
模板:Note
(
编辑
)
模板:Warning
(
编辑
)
模块:Arguments
(
编辑
)
模块:Message box
(
编辑
)
模块:Message box/ambox.css
(
编辑
)
模块:Message box/configuration
(
编辑
)
模块:Yesno
(
编辑
)