2014-04-22 5 views
7

Sto utilizzando una libreria che contiene il seguente codice:Come rimuovere qualificatore const da un puntatore a funzione membro

template <typename M> 
void _register_member(lua_State *state, 
         const char *member_name, 
         M T::*member) { 
    std::function<M(T*)> lambda_get = [member](T *t) { 
       //^ error here 
     return t->*member; 
    }; 
    //... 

Tuttavia questo codice non accetta const puntatori a funzione membro. Passando a tali risultati l'errore Function cannot return function type 'void() const' o qualunque sia il tipo della funzione membro const.

Come rimuovere il qualificatore const dalla funzione membro passata o come si applica std::remove_const?

+0

Ci sono molte domande sul codice. Perché si passa 'M (T *)' come argomento modello a 'std :: function' (dovrebbe essere semplice' M' a causa della logica del programma)? Expression 't -> * member' non può essere usato senza elenco di argomenti come so. Non ha tipo. E così via ... – Constructor

+0

Mi dispiace per 'M (T *)', questa parte è giusta. Ma la costruzione 't -> * member' [senza lista di argomenti come ho detto sopra] può essere usata solo per i membri di dati di classe, non per i membri di funzioni di classe. – Constructor

+0

È strano perché con le funzioni membro non const il codice e la libreria funzionano bene. – Appleshell

risposta

1

Come Adam S notato nei commenti questo errore si verifica quando tenta di compilare this simple code che usa la libreria Selene:

#include <selene.h> 

class C { 
public: 
    bool get() const; 
}; 

bool C::get() const {return true;} 

int main() { 
    sel::State state; 
    state["C"].SetClass<C>("get", &C::get); 
} 

Il compilatore non riesce a compilare il codice in Class.h intestazione. Ci sono due overload di membro funzione _register_member della classe Class in esso:

template <typename T, 
      typename A, 
      typename... Members> 
class Class : public BaseClass { 
private: 

    // ... 

    template <typename M> 
    void _register_member(lua_State *state, 
          const char *member_name, 
          M T::*member) { 
     // ... 
    } 

    template <typename Ret, typename... Args> 
    void _register_member(lua_State *state, 
          const char *fun_name, 
          Ret(T::*fun)(Args...)) { 
     // ... 
    } 

    // ... 

}; 

Il compilatore non può scegliere la seconda di sovraccarico quando un puntatore a un membro const funzione viene passato come terzo argomento. Ci dovrebbe essere un altro sovraccarico che potrebbe accettare un membro della funzione const. Dovrebbe essere dichiarata come segue:

template <typename Ret, typename... Args> 
void _register_member(lua_State *state, 
         const char *fun_name, 
         Ret(T::*fun)(Args...) const) 
              ^^^^^ 

Senza tale sovraccarico il compilatore sceglie il primo di sovraccarico che è stato creato per lavorare con puntatori a membri dati (non funzionare membri) e non riesce a compilare il codice.

Così non si può trattare con i membri const funzione quando si utilizza la versione corrente di Selena biblioteca (in modo da farlo almeno).

+0

Grazie mille! L'aggiunta del terzo sovraccarico (con lo stesso metodo del corpo del secondo) ha funzionato. (Non sono sicuro di poter accettare questa risposta come risposta, in quanto risolve il mio problema originale, ma a quanto pare ho fatto la domanda sbagliata ...) – Appleshell

+0

@AdamS Puoi porre la domanda al riguardo [meta ]. :-) – Constructor

+0

È anche possibile utilizzare un invio di tag per il primo modello di funzione. In questo modo, non è necessario definire modelli per tutte le combinazioni di 'const',' volatile' e ref-qualificatori. Prova solo se 'M' è un tipo di funzione. – dyp

1

Devo dire che per coloro che lo guardavano ora, questo era in effetti un bug nel mio codice (una svista davvero) ed è stato risolto poco dopo l'identificazione del problema.