【问题标题】:c++ template argument match std::function with function pointer [duplicate]c ++模板参数将std :: function与函数指针匹配[重复]
【发布时间】:2019-06-14 22:48:06
【问题描述】:

我有一个函数包装器,它接受一个函数和一个参数列表,并使用这些参数调用函数:

template<typename R, typename... Args>
R wrapper(std::function<R(Args...)> f, Args... args) {
    auto ret = f(args...);
    return ret;
}  

但以下内容无法编译:

int f1(int a, int b) { return a+b; }

wrapper(f1, 1, 2);

上面写着:

不匹配的类型'std::function<_res ...>'和'int (*)(int, int)'

但是,如果我这样做:

wrapper(std::function<int(int, int)>(f1), 5, 10);

...它将是格式正确的,这与编译器错误相矛盾。

为什么编译器不接受第一个版本?

演示跟踪:https://onlinegdb.com/rJWzZIQX4

【问题讨论】:

  • 这里没有矛盾。编译器告诉您std::function&lt;_Res(_ArgTypes ...)&gt;int (*)(int, int) 的类型不同(并且不允许将后者隐式转换为前者)。在您的第二个示例中,您显式转换它以便编译器满意。
  • FWIW,在 C++17 中,std::function&lt;int(int, int)&gt;(f1) 可以缩短为 std::function{f1},以节省您的打字和重复次数。
  • @StoryTeller 嗯,这对我不起作用:candidate template ignored: could not match 'function&lt;int (type-parameter-0-1...)&gt;' against 'int (*)(int, int)'
  • 也高度相关,也告诉你为什么lambdas也有这个问题:stackoverflow.com/questions/9998402/…
  • @lubgr - 有趣。我会认为使用推导/指定的类型就足够了。哦,好吧。

标签: c++ template-argument-deduction


【解决方案1】:

在推导模板参数时,编译器不执行任何转换。因此,在

wrapper(f1, 1, 2);

您正在从int (*)(int, int) 类型的函数指针请求std::function&lt;int(int, int)&gt; 的隐式构造。当显式传递std::function&lt;int(int, int&gt;(f1)时,不需要转换参数,参数推导成功。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-09
    • 1970-01-01
    • 2021-06-13
    • 1970-01-01
    • 2021-12-22
    • 2017-06-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多