【问题标题】:Deducing lambdas to std::function<T>将 lambda 推导出为 std::function<T>
【发布时间】:2017-12-01 18:53:22
【问题描述】:

我实际上是想拥有它,这样我就可以从任何带有捕获的 Lamba 创建一个通用回调:GenericCallback([=]{});

使用以下类:

template<typename T> class GenericCallback : public Callback {
public:
    GenericCallback(const std::function<T>& f) {
        mFunction = f;
    }

    void Call() override {
        mFunction();
    }

    std::function<T> mFunction;
};

问题是它希望我定义模板参数。通常这样做没有问题,但如果我使用任何捕获,无论是使用 [=] 还是特定参数,我都无法将类型推入此结构中。

我的最终目标是稍后在指定条件下简单地调用这些函数。

出现此错误的情况:

int v = 5;
GenericCallback<void()>([=]{ int x = v; });

【问题讨论】:

  • 你能提供一个具体的例子吗?我有一个想法,但不确定在这种情况下是否可行。
  • @Incomputable GenericCallback([=]{});
  • “我无法将类型塞进这个结构中。” 怎么会这样? GenericCallback&lt;void()&gt;{[=]{}} 工作正常。
  • @MikeWeir,您似乎正在寻找类型擦除。您的班级无法做到这一点。事实上,它与std::function 具有相同或更少的功能。
  • @MikeWeir, std::function 可以存储与其给出的签名兼容的任何可调用对象,因此std::function&lt;void()&gt; a([some_int]{ return some_int; }); 完全有效。因此,您可以只拥有一个 std::function&lt;void()&gt; 数组并存储任何不带参数的可调用对象。

标签: c++ templates lambda std-function


【解决方案1】:

您误解了std::function&lt;&gt; 的整个概念,并使问题过于复杂。在这种情况下,您可以使用 std::function&lt;void()&gt; 并将匹配的任何内容绑定到它,只有当您需要更改调用签名时,您才需要更改 &lt;&gt; 中的类型。所以

class Callback {
public:
    using callback_type = std::function<void()>;

    Callback( callback_type cb ) : m_cb( cb ) {}
    void call() { m_cb(); }

private:
    callback_type m_cb;
};

int main()
{
    int v;
    Callback c( [=]{ int x = v; } );
    c.call();
}

很简单,你不需要那里的模板。在这种情况下,您需要更改 std::function 中的类型,前提是您希望 Callback::call() 将某些内容传递给该回调或使其返回某些内容,我怀疑您是否打算这样做。

live example

【讨论】:

  • 你说得对。感谢您为我澄清这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-24
  • 1970-01-01
相关资源
最近更新 更多