【问题标题】:Deducing template parameters from std::function从 std::function 推导出模板参数
【发布时间】:2020-11-09 01:01:59
【问题描述】:

我正在使用静态模板成员函数编写一个小类,试图映射 std::function 及其参数:

class test
{
public:
    template <typename R, typename... Args>
    static double exec(std::function<R(Args...)> func, Args && ... args) {
        func(std::forward<Args>(args)...);
        // do something
        return 0.0;
    }
};

假设我有这些琐碎的功能:

  • void f1() { ; }
  • int f2(int v) { return v; }
  • double f3(int v1, float v2) { return (double)v1 * (double)v2; }

我想这样调用我的test::exec 函数:

test::exec(f1);
test::exec(f2, 4);
test::exec(f3, 1, 3.14f);

我正在使用 Visual Studio,但在第二种情况 (f2) 中出现此错误:

error C2672: 'test::exec': no matching overloaded function found
error C2784: 'double test::exec(std::function<_Ret(_Types...)>,Args &&...)': could not deduce template argument for 'std::function<_Ret(_Types...)>' from 'int (__cdecl *)(int)'

不过,如果我在模板签名中指定类型,它会起作用:test::exec&lt;int, int&gt;(sq, 4); 显然,我想避免这种情况。另外,我不知道如何用这种语法来表达对 f1 的调用。

不指定模板参数的签名是否可以实现这个目标?

【问题讨论】:

  • @NathanOliver 那个目标看起来不对。 OP 根本没有使用 lambda。
  • 你为什么要推导出std::function?为什么不接受函数指针呢?
  • exec 是否有理由想要接受 std::function,而不仅仅是任何可调用的? template &lt;typename F, typename... Args&gt; double exec(F func, Args&amp;&amp; ... args) 应该按您期望的方式工作。
  • @cigien lambda,函数指针,没关系。它们不是std::function,因此无法推断出内部类型。这就是骗子的要旨。
  • @NathanOliver 也许是这样,但那里的解决方案不适合 OP 的问题。您是否建议应在该目标上添加答案?事实上,该解决方案展示了如何推断 R,因为那里的 OP 需要它。就这个问题而言,Igor 的解决方案似乎是最简单的,因为 OP 似乎根本不需要知道 R

标签: c++ templates std-function


【解决方案1】:

编译器无法推断出std:function 参数和返回类型,因为您根本没有传递execstd::function


除了std::function,您可以让exec 接受任意类型的可调用对象(包括函数),然后让编译器推断其签名:

template <typename Func, typename... Args>
static double exec(Func func, Args && ... args);

如果您确实需要知道传递给exec 的函数的返回类型,您可以这样做:

template <typename Func, typename... Args>
static double exec(Func func, Args && ... args) 
{
  using R = decltype(func(args...));
  // ...
}

答案改编自@IgorTandetnik 的cmets。

【讨论】:

  • typename Func 版本,如果你需要知道返回类型,decltype(func(std::forward&lt;Args&gt;(args)...)) 很容易获得
  • @IgorTandetnik 好点,我补充了,谢谢。我也会把函数指针选项留在那里。
  • R(*func)(Args...), Args &amp;&amp; ... args 是有问题的,因为Args 必须以相同的方式推断(这在 OP 的版本中也是有问题的)。使其中一个不可演绎,使用其他模板参数。
  • @Jarod42 扣好像work 就好了。
  • 尝试传递左值或const char*std::string Demo
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-09
  • 1970-01-01
  • 2012-06-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多