TheDarkJuster (Member)
Guru^2
Messaggi: 1620
Iscritto: 27/09/2013
|
Buongiorno a tutti!
Oggi sono qui a chiedere aiuto nella comprensione di un articolo: http://pfultz2.com/blog/2012/07/31/reflection-in-under-100 .... L'articolo si concentra su come aggiungere la reflection alle classi del c++, ma proprio non riesco a capire come funziona..... Qualcuno può illuminarmi?
Next, we define a REFLECTABLE macro to generate the data about each field(plus the field itself). This macro will be called like this:
Codice sorgente - presumibilmente C/C++ |
REFLECTABLE
(
(const char *) name,
(int) age
)
|
|
|
Template (Member)
Pro
Messaggi: 177
Iscritto: 09/12/2015
|
Forse dirò una cavolata, ma... se leggi il codice subito dopo, noti le righe
Codice sorgente - presumibilmente C++ |
#define REFLECTABLE(...) \ static const int fields_n = BOOST_PP_VARIADIC_SIZE(__VA_ARGS__); \ friend struct reflector; \
|
E quindi credo che quello che hai citato tu sia solo il "corpo" della macro (isolato per maggior leggibilità dell'articolo), la quale va effettivamente definita come indicato in quest'altro frammento che ti ho citato
Ultima modifica effettuata da Template il 20/02/2016 alle 15:20 |
|
TheDarkJuster (Member)
Guru^2
Messaggi: 1620
Iscritto: 27/09/2013
|
Oh già.... non lo avevo notato.... Ma rimane il fatto che non riesco a capire l'idea su cui si basa tutto quel codice........
|
|
Template (Member)
Pro
Messaggi: 177
Iscritto: 09/12/2015
|
Su quello non posso aiutarti: so cos'è la reflection, ma credo che nel codice si faccia uso di materiale delle librerie Boost, che conosco solo di fama.
Ultima modifica effettuata da Template il 20/02/2016 alle 23:01 |
|
lumo (Member)
Expert
Messaggi: 449
Iscritto: 18/04/2010
|
È un po' di magia voodoo con template e macro variadiche del C.
Se capisci bene le ultime, la parte con i template non è difficilissima.
Secondo me è meglio tenersi alla larga da certe cose, ma suppongo che tu lo stia facendo per curiosità, quindi invece di sentire una spiegazione di me ti consiglio di prendere il primo pezzo di codice
Codice sorgente - presumibilmente C/C++ |
REFLECTABLE ( (const char *) name, (int) age )
|
E provare ad espanderlo a mano (sia le macro che i template).
La parte boost c'è ma è minima e non è essenziale per la comprensione, puoi espanderla ad intuito.
Ovviamente vedrai che il codice che viene fuori ha senso solo all'interno di una class o di una struct.
|
|
TheDarkJuster (Member)
Guru^2
Messaggi: 1620
Iscritto: 27/09/2013
|
Beh non direi proprio per esperimento....
Io necessito di una funzione che ritorna un oggetto istanza dk classe reflectedObject. Questo oggetto può restituire il nome della classe di cui l'oggetto iniziale è istanza, permettere la lettura e scrittura delle sue proprietà.
Una soluzione da me pensata è quella di usare l'override su GetReflectionObject() e per ogni classe creare a mano una classe derivata di reflectedObject, ma mi sembra un lavoro-suicidio.
Così cercavo di esplorare la strada della generazione di metadati da parte del compilatore, e sono finito in quella pagina.
|
|
TheDarkJuster (Member)
Guru^2
Messaggi: 1620
Iscritto: 27/09/2013
|
Vediamo se anche all'una di notte riesco a capire le cose:
Dato il comportamento di BOOST_PP_VARIADIC_SIZE http://www.boost.org/doc/libs/1_49_0/libs/preprocessor/doc ...
Se io espando
Codice sorgente - presumibilmente C/C++ |
REFLECTABLE ( (const char *) name, (int) age )
|
ottengo:
Codice sorgente - presumibilmente C++ |
static const int fields_n = 2; friend struct reflector;
|
Ho commesso qualche errore in questo punto? |
|
lumo (Member)
Expert
Messaggi: 449
Iscritto: 18/04/2010
|
Devi andare avanti, la parte essenziale è
Codice sorgente - presumibilmente Plain Text |
BOOST_PP_SEQ_FOR_EACH_I(REFLECT_EACH, data, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))
|
le cose usate qui sono definite sotto
|
|
TheDarkJuster (Member)
Guru^2
Messaggi: 1620
Iscritto: 27/09/2013
|
Ok... credo di aver capito: in pratica per ogni campo REFLECTABLE
Codice sorgente - presumibilmente C/C++ |
template<int N, class Self>
struct field_data {};
|
diventa l'espansione di
Codice sorgente - presumibilmente C++ |
PAIR(x); \ template<class Self> \ struct field_data<i, Self> \ { \ Self & self; \ field_data(Self & self) : self(self) {} \ \ typename make_const<Self, TYPEOF(x)>::type & get() \ { \ return self.STRIP(x); \ }\ typename boost::add_const<TYPEOF(x)>::type & get() const \ { \ return self.STRIP(x); \ }\ const char * name() const \ {\ return BOOST_PP_STRINGIZE(STRIP(x)); \ } \ }; \
|
Ma è orribile e non mi permette di documentare le mie classi con doxygen. Quindi non posso usare questo metodo per la reflection.......... |
|