【问题标题】:How to call a created functor object as found in another stackoverflow?如何调用另一个stackoverflow中创建的仿函数对象?
【发布时间】:2016-03-31 17:19:10
【问题描述】:

在stackoverflow 问题Template function that can take lambda or function pointer and deduce arguments for passing to another template 中有一个通过CreateFunctor 调用创建的仿函数对象。如何使用它来调用doSomething

int main(){
    auto f1 = CreateFunctor([](int a, int b){doSomething(a, b);}, 1, 2);
    f1(1,2);
}

不起作用。

http://coliru.stacked-crooked.com/a/954b1f64fd13739e 为例。

【问题讨论】:

  • 最好把错误信息复制到这里。通过阅读错误消息,Functor 似乎没有operator(...) 需要在f1(1,2) 行调用它。另外,Set 函数除了打印 'Set' 什么都不做……我想你需要的是std::bind,不需要自己写(cplusplus.com/reference/functional/bind/?kw=bind

标签: c++ c++11 callback


【解决方案1】:

您引用的帖子中 CreateFunctor 的目的是创建一个函数对象,该对象在构造时将参数绑定到 lambda。

您在调用 CreateFunction 时执行此操作,但在调用函数对象时也会再次传递参数。

因为参数已经绑定,所以这是不必要的(实际上是不可能的)。

只需调用 f1()。

评论:引用的帖子旨在提高绑定函数对象的性能,超过 std::function 已经提供的性能。我怀疑作者过早地进行了优化。 Std::function 已经内置了性能优化。

编辑:在链接末尾找到代码

编译器错误信息非常明确:

./functor.cpp:57:5: error: type 'Functor<int, int>' does not provide a call operator

问题出在这里:

template<class... Args> struct Functor{
    Functor(void (*)(Args...)) {std::cout << "Functor\n" << std::endl;}
    void Set(Args...) {std::cout << "Set\n" << std::endl;}
};

Functor 模板类不完整。它没有定义呼叫运算符(根据错误消息)。

为什么不省去麻烦,使用标准对象呢?

auto f1 = std::function([] { do_something(1, 2); });
f1();

auto f1 = std::function([a = 1, b = 2]{ do_something(a,b); });

【讨论】:

  • 另外,使用std::bind也可以达到同样的效果,只需要使用std lib,比开发已有的功能更可取。
  • Bind 有一些问题,这是基于它在 boost 库中使用 c++98 开发的遗留问题。与 bind 相比,lambda 是一种更好(读起来更安全、更正确)的解决方案。不过总的来说,我完全同意。使用标准算法和对象。
  • @Richard Hodges:不幸的是 f1() 不起作用。错误消息是:main.cpp:33:8: error: no match for call to '(Functor) ()' f1(); ^ main.cpp:33:5: 错误:类型 'Functor' 不提供调用运算符 f1(); ^~
  • @BerndL。如果您需要帮助解决它,您需要提供一个完整的示例(我几乎可以编译成程序的源代码)。我需要查看您的代码和 CreateFunction 的定义
  • @BerndL。更新答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-04
  • 1970-01-01
相关资源
最近更新 更多