2015-10-20 7 views
5

Voglio scrivere una macro che, quando espansa all'interno di una classe, usa quel tipo di classe (in particolare, come argomento del template). All'interno metodo di classe, posso usare questo:C++ - Ci sono modi per ottenere il tipo di classe corrente con la sintassi invariabile?

#define METHOD_MACRO int sample_method(void)const {\ 
    return template_struct<this_type<decltype(this)>::type>::index;} 

(this_type è il mio struct, qui è equivalente a remove_pointer<remove_const<T>>)

Ma quando ho bisogno di tipo di classe al di fuori del metodo (per typedef per il puntatore membro della classe), La parola chiave this non è disponibile; Ho provato a usare auto per qualche trucco con tipo deducente, ma senza fortuna qui. Le classi in questione sono ereditate dalla mia classe, se questo può essere di qualche aiuto. Vorrei evitare che nessuno usi la mia macro per scrivere obbligatoriamente typdedef.

Qualche idea?

+2

Utilizzare CRTP? Forse è possibile eliminare del tutto le macro ... –

+0

Ciò richiede uno sforzo esplicito da parte dell'utente, che cerco di evitare il più possibile. Idea interessante, ma non del tutto lì. – Abstraction

+1

@Abstraction Digitando il nome della tua macro richiede tanto sforzo esplicito da parte dell'utente che ereditare da una classe con CRTP :) – Drax

risposta

4

È possibile utilizzare il seguente trucco:

#define SELF \ 
    static auto helper() -> std::remove_reference<decltype(*this)>::type; \ 
    typedef decltype(helper()) self 

struct A { 
    SELF; 
}; 

dichiaro una funzione di supporto utilizzando il tipo auto ritorno, che mi permette di usare decltype(*this) come un tipo di ritorno, non sapendo che cosa è il nome della classe. Quindi posso usare decltype(helper()) per usare il tipo di classe nel codice. Si noti che la funzione deve essere static, altrimenti non è possibile utilizzarla in decltype. Anche la funzione è appena dichiarata, non definita; questo non dovrebbe essere un problema visto che non lo chiamerai comunque. (È possibile aggiungere un corpo vuoto ad esso, ma sarà sollevare un avvertimento che una funzione non ha return. Ancora si può cambiare il tipo di ritorno per essere decltype(this) e tornare nullptr.)

Si può quindi utilizzare il typedef self per ulteriori dichiarazioni, o semplicemente alterare le macro per typedef non la classe stessa, ma ciò che è necessario. Regola per soddisfare le tue particolari esigenze.

UPD: Questo sembra essere un comportamento non standard di GCC. Ad esempio, ICC non consente this nelle funzioni static anche nel tipo di ritorno finale.

+2

Perché puoi usare "questo" in questo contesto? –

+0

@ n.m., Perché non posso? Non sono esperto nello standard, ma la mia comprensione approssimativa è che "questo" è solo un parametro di funzione implicito, e posso usare i parametri di funzione nel tipo restituito con "auto". E funziona: http://coliru.stacked-crooked.com/a/9af8022707a13ff6 – Petr

+0

@ n.m, sebbene io sia davvero strano avere "questo" in una funzione 'statica'. Inizialmente cercavo di renderlo come non statico, aggiungendo 'static' per rendere' decltype (helper()) 'funzionante, e non rendersi conto che' decltype (* this) 'poteva rompersi. Comunque, funziona. Non dire che è un errore di GCC :) – Petr

Problemi correlati