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?

muffel
  • 7,004
  • 8
  • 57
  • 98

2 Answers2

2

The following work-around works:

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

void(*func_pointer)(void) = []{
    global_instance<Singleton>()->bar();
};
Daniel Frey
  • 55,810
  • 13
  • 122
  • 180
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);
}
6502
  • 112,025
  • 15
  • 165
  • 265
  • `T` seems like a poor name choice for that type. – Yakk - Adam Nevraumont Oct 22 '13 at 10:25
  • @Yakk: IMO `LocalStructureNeededBecauseCppDoesntAllowLocalFunctions` would have been worse :-) – 6502 Oct 22 '13 at 12:04
  • @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. – 6502 Oct 22 '13 at 12:08
  • Why oh why are the semantics of a lambda any different from those of an inline struct... – Cuadue Jan 27 '15 at 02:50
  • @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++. – 6502 Jan 27 '15 at 07:10