2013-10-22 19 views
5

Si consideri il seguente codice:C++ Lambda: metodo statico di accesso in lambda induce in errore 'questo non è stato catturato per questa funzione lambda'

//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); 
} 

voglio chiamare una funzione che non posso modificare (vedi some_library_method sopra) che si aspetta un puntatore a funzione come argomento. La chiamata dovrebbe essere effettuata in un membro della classe foo(). So che non posso accedere ai membri della classe, ma tutto quello che voglio fare è accedere alla classe Singleton in modo statico (recuperare l'istanza di singleton).

C'è un modo in cui la riforma espressione lambda per mostrare il compilatore di destinazione, g ++ v4.7.2, che lo fa davvero non bisogno di un riferimento a this?

risposta

2

Il seguente work-around funziona:

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

void(*func_pointer)(void) = []{ 
    global_instance<Singleton>()->bar(); 
}; 
+0

grande, grazie – muffel

1

È possibile utilizzare una funzione regolare definita a livello locale, invece di un lambda per quella

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

'T' sembra come un povero scelta del nome per quel tipo. – Yakk

+0

soluzione interessante, grazie! – muffel

+0

@Yakk: IMO 'LocalStructureNeededBecauseCppDoesntAllowLocalFunctions' sarebbe stato peggio :-) – 6502