我收到以下错误
min.cpp:17:30: error: no viable conversion from '<overloaded function type>' to 'Container::UnaryFun' (aka 'function<double (double)>')
this->addFunction("abs", abs);
Run Code Online (Sandbox Code Playgroud)
当尝试编译以下代码时:
#include <cmath>
#include <string>
#include <functional>
class Test
{
public:
using UnaryFun = std::function<double (double)>;
Test()
{
this->addFunction("abs", abs);
}
auto addFunction(const std::string& name, UnaryFun fun) -> void
{
// ...
}
};
auto main() -> int {
Test eval;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我尝试检查std::absfor 参数double和返回类型的声明double,如下所示:
inline _LIBCPP_INLINE_VISIBILITY double abs(double __lcpp_x) _NOEXCEPT {
return __builtin_fabs(__lcpp_x);
}
Run Code Online (Sandbox Code Playgroud)
在/usr/local/Cellar/llvm/15.0.7_1/include/c++/v1/stdlib.h。
它是专门针对该double类型的。我已经通过添加检查了这一点:
double a = 5;
double b = std::abs(a);
Run Code Online (Sandbox Code Playgroud)
并且编译时没有问题或转换警告。
我尝试abs像这样声明我自己的函数:
inline double xabs(double val)
{
return val < 0 ? -val : val;
}
Run Code Online (Sandbox Code Playgroud)
然后像这样更改以下代码以使用这个新的xabs而不是std::abs
this->addFunction("abs", xabs);
Run Code Online (Sandbox Code Playgroud)
进行此更改后,代码可以编译。
有什么想法为什么代码std::abs无法编译吗?
我的环境: 操作系统:Mac OS 12.6
编译器:
Apple clang version 14.0.0 (clang-1400.0.29.202)
Target: x86_64-apple-darwin21.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
Run Code Online (Sandbox Code Playgroud)
编译命令:g++ -std=c++2a -o min min.cpp
根据评论更新
我深挖了一下,似乎是std::function声明方式有问题,才导致了上面的问题。
如果我addFunction像这样声明,没有std::function,问题就消失了。
auto addFunction(const std::string& name, double (*fun)(double)) -> void
{
}
Run Code Online (Sandbox Code Playgroud)
这意味着编译器无法确定是否使用了匹配的absif std::function,但如果直接描述函数的类型而不使用 ,它可以识别匹配的重载std::function。
问题是,由于它有多个重载,因此std::abs没有单一类型。这意味着编译器无法选择std::function用于转换它的构造函数,因为它无法推断构造函数的模板参数的类型。
有几种方法可以解决这个问题:
addFunction("abs", std::static_cast<double(*)(double)>(std::abs));
Run Code Online (Sandbox Code Playgroud)
addFunction("abs", [](double d) { return std::abs(d); });
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
143 次 |
| 最近记录: |