Anonymous function C++

anonymous-function, c++, c++11, lambda

Solution

There is no such thing as an anonymous function in C (C++ is irrelevant here, as the function must abide by the C calling convention).

The only thing you can do is shiver access globals from the handler, probably global variables (and not constants which would be fine).

I advise making those globals thread local to avoid multithreading issues, but it is still bad in the sense that global variables make for more brittle applications.

How to ?

Note: as Luc Danton patiently explained to me, a signal may interrupt any non-atomic activity, and thus reading from a global is safe only if it is a lock-free atomic (or a few other things). Unfortunately `std::function` may not be so, depending on your implementation, I will still leave this code to explain how it could be done providing that `std::function` accesses are atomic.

It is possible to create a trampoline that will call stateful stuff, isolating thread and allowing re-entrant calls.

typedef std::function<void(int)> SignalHandlerType;

extern thread_local ignalHandlerType SignalHandler;

And we create the following accessor (passed to signal):

void handle_signal(int const i) {
    if (SignalHandler) { SignalHandler(i); }
}

as well as the following RAII setter:

class SignalSetter: boost::noncopyable {
public:
    SignalSetter(int signal, SignalHandlerType&& sh):
        signal(signal), chandler(0), handler(sh)
    {
        chandler = std::signal(signal, &handle_signal<T>);
        swap(SignalHandler, handler);
    }

    ~SignalSetter() {
        std::signal(signal, chandler);
        swap(SignalHandler, handler);
    }

private:
    typedef void(*CHandlerType)(int);

    int signal;
    CHandlerType chandler;
    SignalHandlerType handler;
};

Note: both the global variable and the `handle_signal` could be `private` to the `SignalSetter` class... but since `std::signal` is not...

Expected usage:

int main(int argc, char* argv[]) {
    SignalSetter setter(SIGFPE, [argc, argv]() {
        std::cout << argc << ": " << argc << std::endl;
    });

    // do what you want.
}

Problem

I am trying to use the function `signal(int,void(*)(int))` from `<csignal>` to handle the floating point exception SIGFPE. I'd like to be able to print some useful diagnostics besides just a message saying "Floating point exception" or something to that effect. This means the function I pass as the handler to `signal` needs access to some of the data in my code. Therein lies the rub. The function must return `void` and accept only 1 parameter of type `int`. I cannot make the handler a member function of my data storage class since then the type would be `void(Foo::*)(int)` due to the hidden `this` pointer. I thought about using lambdas to try and make an anonymous function like this; ``` void handler(int nSig, Foo data) { // do something } // snip Foo data; signal(SIGFPE, [&](int nSig)->void{handler(nSig,data);}); ``` however because the lambda captures the variable `data` from outside the compiler will not let it be cast to a pointer to `void(*)(int)` (which is a shame as this seems like an ideal use for lambdas). I could simply make `data` a global variable which could then be seen in `handler` but I am loath to do this for obvious reasons. So my question is thus; what is the best way of mimicking anonymous functions in C++? Note: I would prefer a native C++ solution and not to have to use boost or equivalent.

Original source