C++如何将带不同参数的函数存入std::function类型的map中
问题原因分析
你原有写法报错的核心原因有两个:
std::bind返回的是带绑定状态的可调用对象,不是普通的裸函数指针,因此你尝试强转为double(*)(const std::vector<float>&)类型本身就是非法操作。- 你的map值类型本身就是
std::function类型,天生支持兼容符合签名的所有可调用对象,完全不需要做函数指针强转,你之前给普通函数加的static_cast也是完全多余的操作。
带额外参数的函数存入方案
方案1:修正std::bind的写法
你需要给未绑定的vector参数添加占位符,不需要强转直接存入即可:
// 记得引入std::placeholders命名空间 using namespace std::placeholders; f_map.emplace("2000", std::bind(func2, 1, _1));
这里的_1是占位符,表示调用std::function时传入的第一个参数(也就是你的vector参数)会被转发给func2的第二个入参。
方案2(更推荐):使用Lambda表达式
Lambda可读性远高于std::bind,也不容易出现参数顺序匹配错误的问题:
f_map.emplace("2000", [](const std::vector<float>& v) { return func2(1, v); });
如果需要绑定运行时动态的值,直接通过lambda捕获即可,语法更加灵活。
更优的实现方案优化建议
- 去掉多余的强转操作:普通函数可以直接存入
std::function,不需要转函数指针,原来的注册逻辑可以简化为:f_map.emplace("2015", func1); // 不需要static_cast,直接传入即可 - 新增注册辅助函数做编译期校验:可以避免传错函数签名时出现冗长晦涩的编译报错:
后续注册时直接调用即可:template<typename Callable> void register_function(const std::string& key, Callable&& callable) { // 校验传入的可调用对象是否符合返回值、参数要求 static_assert( std::is_invocable_r_v<double, Callable, const std::vector<float>&>, "注册的函数必须返回double类型,且可接收const std::vector<float>&作为唯一参数" ); f_map.emplace(key, std::forward<Callable>(callable)); }register_function("2015", func1); register_function("2000", [](const auto& v) { return func2(1, v); }); - 如果需要支持同个key对应多个函数,可以改用
std::unordered_multimap,或者值类型改为std::vector<func>。
内容的提问来源于stack exchange,提问作者nick
相关产品推荐
相关产品推荐

