<p>std::function 本身是类型模板,不能取地址;需对具体变量取址,如 std::function* p = &my_func;误用类型名、临时对象或跨线程裸指针易导致崩溃。</p>

std::function 本身不能取地址,所以不能定义指向它的指针
直接写 &std::function 会编译失败,因为 std::function 是一个类型模板(如 std::function<void></void>),不是变量;而你真正想操作的,是某个具体变量的地址。常见误解是以为“std::function 类型像函数指针一样可被取址”,但其实它是个可调用对象包装器,内部有状态、可能捕获闭包,不支持简单取址。
想间接持有 std::function 变量?用 std::function* 或 std::shared_ptr<:function>>
如果你需要传递或存储对某个 std::function 实例的引用(比如在回调注册表里动态修改目标),实际可行的方式是:
- 用原始指针:
std::function<void>* func_ptr = &my_func;</void>—— 要确保my_func生命周期长于该指针的使用期,否则悬空 - 用智能指针:
std::shared_ptr<:function>> func_ptr = std::make_shared<:function>>([](int x) { /* ... */ });</:function></:function>—— 适合需要共享所有权或延长生命周期的场景 - 更常见的是直接传值或 const 引用:
void register_callback(const std::function<void>& f)</void>,避免裸指针管理负担
为什么不用函数指针替代 std::function*
函数指针(如 void(*)(int))和 std::function<void></void> 不兼容:前者只能指向普通函数或 lambda(无捕获),后者能包装任意可调用体(含捕获 lambda、bind 表达式、成员函数等)。所以即使你写了 void(*fp)(int) = &some_free_func;,也不能赋给 std::function<void>*</void> 所指向的对象——类型不匹配,编译报错 cannot convert 'void(*)()' to 'std::function<void>' in assignment</void>。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
实际中容易踩的坑
最常出问题的是误以为 std::function 可以像 C 函数指针那样“一等公民式”地传递地址:
立即学习“C++免费学习笔记(深入)”;
- 把局部
std::function变量的地址存到容器里,离开作用域后解引用崩溃 - 试图对临时对象取址:
&std::function<void>{[](){}}</void>—— 编译不过,临时对象不能绑定到非 const 引用,更别说取址 - 混淆类型名和变量名:写
std::function<void>* p = &std::function<void>;</void></void>—— 这是语法错误,std::function<void></void>是类型,不是变量 - 跨线程共享裸指针指向的
std::function,没加锁,导致调用时内部状态被破坏
真正要做的,往往不是“定义指向 std::function 的指针”,而是决定要不要转移/共享/延迟调用这个可调用对象——这时候选 std::function 值语义、std::reference_wrapper 或智能指针,比裸指针安全得多。

















