0

In the stackoverflow question Template function that can take lambda or function pointer and deduce arguments for passing to another template there is a functor object created through the CreateFunctor call. How can I use it to invoke doSomething?

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

Does not work.

See http://coliru.stacked-crooked.com/a/954b1f64fd13739e as example.

Community
  • 1
  • 1
Bernd L.
  • 59
  • 8
  • It better to copy here the error message. And by reading error message, it appears that `Functor` have no `operator(...)` needed to call it at line `f1(1,2)`. Also, `Set` function does nothing else than printing 'Set'... I think what you need is `std::bind`, no need to write it by yourself (http://www.cplusplus.com/reference/functional/bind/?kw=bind) – Garf365 Mar 31 '16 at 08:00

1 Answers1

1

The purpose of CreateFunctor in the post you cite is to create a function object which binds the arguments to the lambda at the time of construction.

You do this in the call to CreateFunction, but you also pass the arguments again when you call the function object.

Because the arguments are already bound, this is un-necessary (and indeed not possible).

Simply call f1().

Comment: the post cited seeks to improve the performance of a bound function object over that already provided by std::function. I suspect the author is prematurely optimising. Std::function already has performance optimisations built in.

EDIT: of found the code at the end of the link

The compiler error message is quite explicit:

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

The problem is here:

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

The Functor template class is incomplete. It does not have a call operator defined (as per the error message).

Why not save yourself the trouble and use the standard objects?

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

or

auto f1 = std::function([a = 1, b = 2]{ do_something(a,b); });
Richard Hodges
  • 68,278
  • 7
  • 90
  • 142
  • also, by using `std::bind`, same thing can be achieved, just by using std lib, which is preferable as developing already existing function. – Garf365 Mar 31 '16 at 08:11
  • Bind has some issues, which are based in its legacy of being developed in c++98 in the boost library. A lambda is a better (read safer and more correct) solution than bind. In general though, I totally agree. Use std algorithms and objects. – Richard Hodges Mar 31 '16 at 08:19
  • @Richard Hodges: Unfortunately f1() does not work. Errormessage is: main.cpp:33:8: error: no match for call to '(Functor) ()' f1(); ^ main.cpp:33:5: error: type 'Functor' does not provide a call operator f1(); ^~ – Bernd L. Mar 31 '16 at 09:00
  • @BerndL. you'll need to provide a complete example (source code i can almost compile into a program) if you want help solving it. I need to see your code and the definition of CreateFunction – Richard Hodges Mar 31 '16 at 09:11
  • 1
    @BerndL. Updated answer – Richard Hodges Mar 31 '16 at 09:21