如何将C++模板函数中的float(*fSqrt)(float)替换为std::function?
错误原因
编译报错的核心诱因有两点:
std::sqrt是多重重载的函数,存在float sqrt(float)、double sqrt(double)、long double sqrt(long double)等多个版本,直接传递函数名时编译器无法自动判定要匹配哪个重载版本,自然无法完成到std::function<float(float)>的隐式转换。- 当你使用模板参数
Type作为std::function的入参类型时,std::function属于非推导上下文,编译器无法从你传递的std::sqrt反推Type的类型,进一步加剧了匹配失败的问题。
解决方案
方案1:仅修改调用侧(适用于不想调整函数定义的场景)
调用时显式指定std::sqrt的重载版本,同时可选显式指定模板参数Type避免推导失败:
// Type为int时的调用示例,对应std::function<float(float)>版本的函数 isPrime<int>(n, static_cast<float(*)(float)>(std::sqrt), true); // 如果你已经升级为std::function<float(Type)>的最终版本,对应调整强转类型即可 isPrime<int>(n, static_cast<float(*)(int)>(std::sqrt), true);
不想强转函数指针的话,也可以用一层lambda消除重载歧义:
// 对应std::function<float(float)>版本 isPrime(n, [](float x) { return std::sqrt(x); }, true); // 对应std::function<float(Type)>的最终版本,通用lambda适配所有Type类型 isPrime(n, [](const auto& x) { return std::sqrt(x); }, true);
方案2:修改函数定义侧(调用侧无需改动,使用更友好)
不要直接把std::function放在模板参数的推导上下文里,单独新增一个模板参数接收可调用对象,同时内置默认的sqrt实现,满足你最终要使用Type作为入参的需求:
#include <functional> #include <cmath> template<class Type, class SqrtFunc = std::function<float(Type)>> bool isPrime(const Type& n, SqrtFunc fSqrt = [](const Type& val) { return std::sqrt(val); }, bool debug = false) { // 此处保留你原有的函数逻辑即可 }
按上述方式定义后,你原来的调用写法isPrime(n, std::sqrt, true)可以直接正常运行,甚至不需要调用方手动传sqrt参数也可以直接调用。
内容的提问来源于stack exchange,提问作者Supreeto
相关产品推荐
相关产品推荐

