Ho il seguente codice di base:Funzione prendendo sia puntatore a membro-funzione e puntatore a const membro funzione
template <typename Type>
class SomeClass {
public:
template <typename ReturnType, typename... Params>
void register_function(const std::pair<std::string, ReturnType (Type::*)(Params...)> fct) {
auto f = [fct](Params... params) -> ReturnType { return (Type().*fct.second)(std::ref(params)...); }
// ...
}
};
Questo funziona quando passo un puntatore ad un organo-funzione (non-const). Tuttavia, se voglio passare un puntatore a un membro funzione const, il risultato e 'un errore di compilazione e devo duplicare la funzione di cui sopra per ottenere questo codice:
template <typename Type>
class SomeClass {
public:
template <typename ReturnType, typename... Params>
void register_function(const std::pair<std::string, ReturnType (Type::*)(Params...)> fct) {
auto f = [fct](Params... params) -> ReturnType { return (Type().*fct.second)(std::ref(params)...); }
// ...
}
template <typename ReturnType, typename... Params>
void register_function(const std::pair<std::string, ReturnType (Type::*)(Params...) const> fct) {
auto f = [fct](Params... params) -> ReturnType { return (Type().*fct.second)(std::ref(params)...); }
// ...
}
};
Ora, posso passare sia const- funzioni membro e funzioni membro non const. Ma, ora, il codice è duplicato e la manutenibilità è ridotta.
C'è un modo per unire queste due funzioni in una funzione tenendo entrambe le funzioni const-member e non-const-member?
Nota importante: Devo davvero utilizzare una funzione puntatore come parametro (nessuna funzione std ::).
Modifica: ho aggiunto un po 'di codice in più. All'interno delle funzioni, costruisco una chiusura che corrisponde alla firma della funzione membro (stessi tipi di ritorno e parametri). Tale chiusura verrà memorizzato e utilizzato in seguito per la realizzazione di riflessione (more here)
Perché non semplicemente 'template register_function void (Fun FCT)'? –
fredoverflow
Ho aggiornato la mia domanda con un po 'di codice in più. All'interno di lambdas, potrei chiamare std :: bind o usare direttamente il puntatore di funzione membro su una nuova istanza di oggetto. Questo è il motivo per cui ho davvero bisogno di accedere a ReturnType e ai nomi dei tipi Params. –
È tutta la tua base di codice? lol davvero –