2011-12-12 11 views
5

Supponiamo di avere un tipo my_struct che racchiude una variabile membro, f, che è una funzione. È possibile che f sia una funzione lambda C++ 11.Come rilevare se un tipo è un'espressione lambda in fase di compilazione?

Poiché è illegale assegnare oggetti lambda, vorrei implementare l'operatore di assegnazione di my_struct in modo tale che quando f è un lambda, non è assegnato.

È possibile creare un tratto di tipo is_lambda che può ispezionare un tipo per lambda-ness?

in codice:

#include <type_traits> 

template<typename Function> struct is_lambda 
{ 
    // what goes here? 
}; 

template<typename Function> struct my_struct 
{ 
    Function f; 

    my_struct &do_assign(const my_struct &other, std::true_type) 
    { 
    // don't assign to f 
    return *this; 
    } 

    my_struct &do_assign(const my_struct &other, std::false_type) 
    { 
    // do assign to f 
    f = other.f; 
    return *this; 
    } 

    my_struct &operator=(const my_struct &other) 
    { 
    return do_assign(other, typename is_lambda<Function>::type()); 
    } 
}; 

risposta

7

impossibile senza il supporto del compilatore, come il tipo di un lambda è solo un normale, tipo di classe non sindacale.

§5.1.2 [expr.prim.lambda] p3

Il tipo di lambda-espressione (che è anche il tipo di oggetto di chiusura) è un unico, senza nome tipo classe pseudoartrosi [...]

4

Presumibilmente non si desidera assegnare funzioni non assegnabili non lambda, quindi è possibile utilizzare std::is_assignable.

+0

Questo sembra funzionare in Visual C++ 2015, forse anche nelle versioni precedenti. Usando semplicemente: 'std :: is_assignable :: value'. Ho usato questo metodo per garantire che una lambda non derivasse da quando si utilizza _EBO_. –

+0

@MatthewHolder Questo tipo di punto manca la mia risposta, che è che non dovresti provare a dare un trattamento speciale a lambda. Non c'è nulla di intrinsecamente sbagliato nel derivare da un lambda. Ha alcuni aspetti che possono renderlo complicato, ma quegli stessi aspetti possono essere applicati alle classi non lambda. Il fatto che non siano assegnabili non è uno di loro, quindi nel tuo caso, penso che non sia l'aspetto da controllare. – hvd

+0

Comprensibile, ma una situazione che mi richiedeva di rilevare un lambda era quando si passa un oggetto FunctionObject a un argomento del tipo di modello di classe che verrà utilizzato come classe base del modello di classe per Empty Base Optimization. Dal momento che non è possibile ereditare un tipo di lambda in determinate situazioni o su determinati compilatori. Come questa situazione migliora ... non sarà più un problema. –

Problemi correlati