20

Basically I want to do this: Can I use a lambda function or std::function object in place of a function pointer?

clearly that is impossible for now for functions that expect a function pointer. However, it will work for a function that expects a functor ( I have done it before with stl's sort() function)

However, I don't know how to write a function that takes a functor as an argument!

Anyone?

Community
  • 1
  • 1
aCuria
  • 6,935
  • 14
  • 53
  • 89
  • "clearly that is impossible" - actually, it _is_ possible. However, only stateless lambda's can be converted to function pointers. – MSalters Oct 17 '11 at 08:56

3 Answers3

26

Just write the function to take an arbitrary type:

template <typename Func>
void foo(Func fun)
{
    fun(...);
}

This will then work with function pointers, functors and lambdas all the same.

void f() {}

struct G
{
    void operator()() {}
};

foo(&f);           // function pointer
foo(G());          // functor
foo([]() { ... }); // lambda
ajp013
  • 173
  • 1
  • 6
Peter Alexander
  • 53,344
  • 14
  • 119
  • 168
  • This leaves questions. The example mentioned in [another answer](http://stackoverflow.com/a/356993/6049796) includes a functor with local variable. Will the `add42` get exactly `42` upon evaluation if I pass it as `add42()` and not `add42`? – Euri Pinhollow Nov 23 '16 at 14:40
  • This is not a typesafe solution, if you want to pass in a function, use std::function like fredoverflow's answer below. – sprite Dec 05 '18 at 08:54
  • @sprite (that comment is old but) Note that `std::function` incurs runtime overhead; besides, what does it mean to be "not typesafe"? This function will raise a compile error if the provided function can't be called (but at the actual function call `fun(...)` in the implementation instead of the `foo(...)` line. – user202729 Feb 01 '21 at 06:48
26

I don't know how to write a function that takes a functor as an argument!

Since nobody has posted the std::function solution yet:

#include <functional>
#include <iostream>

void foo(std::function<int(int)> f)
{
    for (int i = 0; i < 10; ++i)
    {
        std::cout << f(i) << ' ';
    }
    std::cout << '\n';
}

int main()
{
    foo( [](int x) { return x*x; } );
}

You can use boost::function in pre C++11 compilers.

fredoverflow
  • 256,549
  • 94
  • 388
  • 662
  • 3
    @Kerrek : Why is that a good thing? This causes pointless type erasure, i.e. an unnecessary runtime performance hit. I would argue that `std::function<>` should only be used if non-local persistence is required. – ildjarn Oct 16 '11 at 22:02
  • 2
    @ildjarn: Perhaps. It's impossible to argue the pros and cons without knowing the actual function body and application. You're right that the templated version has certain advantages, but it's good to know about the non-template approach, too. – Kerrek SB Oct 16 '11 at 22:06
  • @Kerrek : That I can agree with. :-] – ildjarn Oct 16 '11 at 22:06
6

It has to be a template, like:

template<class F>
void foo( const F& f )
{
    f(x,y);
}
PlasmaHH
  • 15,673
  • 5
  • 44
  • 57
  • 2
    Functors are usually passed by value. – fredoverflow Oct 16 '11 at 21:58
  • @FredOverlow: I would say that is a personal preference. I personally tend to usually use pass by const-ref. – PlasmaHH Oct 16 '11 at 22:01
  • 3
    @PlasmaHH : There's more to it than personal preference, the nit being that your way requires a const `operator()` definition whereas passing by value doesn't. `std::for_each`, for example, could not work your way. – ildjarn Oct 16 '11 at 22:05
  • @ildjarn: Sure, but we are talking from the POV of the writer of such a function. I personally write mostly templates that forward their functors elsewhere, and I want to enable people to keep a state. – PlasmaHH Oct 16 '11 at 22:08
  • 1
    @PlasmaHH : But how can they keep a state if you require that their `operator()` be const? – ildjarn Oct 16 '11 at 22:09
  • 4
    While that's a technically correct response, it doesn't answer the spirit of the question -- if you specifically want to _support_ stateful functors, why would you force the functor author to hack around const-correctness rules, when passing by value (as the standard library does, which sets quite a precedent IMO) would make her work painless? – ildjarn Oct 16 '11 at 22:12
  • @ildjarn: because in my context, functors are usually temporaries, or people want to use temporaries. – PlasmaHH Oct 16 '11 at 22:28
  • @PlasmaHH : Given any modern compilers' copy-elision optimization support, passing by value and passing by const-reference are 100% equally efficient when passing a temporary. I.e., that's irrelevant. ;-] – ildjarn Oct 16 '11 at 22:30
  • @ildjarn: not really. requirement1: "pass by reference", requirement2: "pass temporaries". solution: refrences to const. – PlasmaHH Oct 17 '11 at 13:36
  • @PlasmaHH : Your requirement1 is nonsensical -- who says passing by reference is a good thing in this scenario? The real requirement1 is "design for stateful functors". – ildjarn Oct 17 '11 at 16:02
  • @ildjarn: oh yeah, and I assume the canonical solution to that is pass by value of objects that have a shared pimpl pointer? – PlasmaHH Oct 17 '11 at 16:12