5

Consider the following code:

//this is what I want to call; I cannot modify its signature
void some_library_method(void(*fp)(void));

class Singleton{
    public:
        static Singleton *instance();
        void foo();
        void bar();
    private:
        Singleton();
};

void Singleton::foo(){
    //this leads to an error ('this' was not captured for this lambda function)
    void(*func_pointer)(void) = []{
        Singleton::instance()->bar();
    };
    some_library_method(func_pointer);
}

I want to call a function I cannot modify (see some_library_methodabove) which expects a function pointer as an argument. The call should be done in a class member foo(). I do know that I cannot access class members there, but all I want to do is access the Class Singleton in a static way (retrieve the singleton instance).

Is there any way reform the lambda expression to show the target compiler, g++ v4.7.2, that it really does not need a reference to this?

0

2 Answers 2

2

The following work-around works:

template< typename T > T* global_instance() { return T::instance(); }

void(*func_pointer)(void) = []{
    global_instance<Singleton>()->bar();
};
Sign up to request clarification or add additional context in comments.

Comments

1

You can use a locally defined regular function instead of a lambda for that

void Singleton::foo() {
    struct T {
        static void cb(){ Singleton::instance()->bar(); }
    };
    some_library_method(T::cb);
}

5 Comments

T seems like a poor name choice for that type.
@Yakk: IMO LocalStructureNeededBecauseCppDoesntAllowLocalFunctions would have been worse :-)
@muffel: Unfortunately local structures cannot be used with templates for an explicit limitation specified in the standard that I don't understand and that was present in C++03 and has been IIRC inherited also by C++11. Still you can use them to declare local callbacks without having to place the callback code far from the use and without polluting the module namespace.
Why oh why are the semantics of a lambda any different from those of an inline struct...
@Cuadue: lambdas (closures) can access locals and this is very powerful in general (just happens of not being needed in this case). Unfortunately to really appreciate the full power of reference-capturing closures the language needs to provide garbage-collect based lifetime for locals (not only stack based lifetime) but this would have been too much of a change for C++.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.