如何将std::sqrt赋值给std::function?复数可用实数不可用的原因是什么?
编译错误原因
首先,<cmath>中提供的实数版std::sqrt是多重重载的普通函数,不是函数模板,包含以下常见重载:
float sqrt(float)double sqrt(double)long double sqrt(long double)- 以及所有整数类型的重载(会隐式转为double计算)
当你直接取std::sqrt、std::sqrt<float>的地址时,编译器无法从当前上下文判断你要选择哪一个重载版本,而std::function的构造函数本身也是模板,无法自动推导匹配到正确的重载签名,因此报「未决议的重载函数类型」错误。
而std::complex版本的std::sqrt是函数模板,声明为template<class T> std::complex<T> sqrt(const std::complex<T>&),你写std::sqrt<double>时会直接实例化出对应complex<double>的唯一模板函数,没有重载歧义,因此可以正常赋值给对应的std::function。
正确实现方式
方法1:使用lambda包装(最推荐,写法简洁无歧义)
这也是你示例中已经验证可行的方案,lambda内部调用std::sqrt时会自动根据参数类型匹配正确的重载:
// float版本 std::function<float(float)> a = [](float x) { return std::sqrt(x); }; // double版本 std::function<double(double)> d = [](double x) { return std::sqrt(x); };
方法2:强制转换为指定签名的函数指针
通过static_cast明确指定要取哪一个重载的函数地址,消除歧义:
// 明确指定取float(float)版本的重载地址 std::function<float(float)> b = static_cast<float(*)(float)>(std::sqrt); // 明确指定取double(double)版本的重载地址 std::function<double(double)> d = static_cast<double(*)(double)>(std::sqrt);
内容的提问来源于stack exchange,提问作者kid
相关产品推荐
相关产品推荐

