Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - Reflection
Forum - C/C++ - Reflection

Avatar
TheDarkJuster (Member)
Guru^2


Messaggi: 1452
Iscritto: 27/09/2013

Segnala al moderatore
Postato alle 11:44
Sabato, 20/02/2016
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++

  1. REFLECTABLE
  2. (
  3.     (const char *) name,
  4.     (int) age
  5. )


ma non doveva essere una macro? Non inizia con #define ? dubito quel codice sia valido........

Io dopo averlo letto rimango con una enorme perplessità........... :noway::noway::noway::noway::noway:

PM Quote
Avatar
Template (Member)
Pro


Messaggi: 175
Iscritto: 09/12/2015

Segnala al moderatore
Postato alle 15:19
Sabato, 20/02/2016
Forse dirò una cavolata, ma... se leggi il codice subito dopo, noti le righe

Codice sorgente - presumibilmente C++

  1. #define REFLECTABLE(...) \
  2. static const int fields_n = BOOST_PP_VARIADIC_SIZE(__VA_ARGS__); \
  3. 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


"Nel curriculum scrivete quello che sapete fare... e anche quello che non sapete fare! Tipo: "Già vescovo di Cracovia, partecipai alla Coppa America, vincendola!""
[...]
"Sto giocando al piccolo Dio e mi sta venendo pure alla grande."
PM Quote
Avatar
TheDarkJuster (Member)
Guru^2


Messaggi: 1452
Iscritto: 27/09/2013

Segnala al moderatore
Postato alle 15:31
Sabato, 20/02/2016
Oh già.... non lo avevo notato.... Ma rimane il fatto che non riesco a capire l'idea su cui si basa tutto quel codice........:om::om::om:

PM Quote
Avatar
Template (Member)
Pro


Messaggi: 175
Iscritto: 09/12/2015

Segnala al moderatore
Postato alle 23:00
Sabato, 20/02/2016
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


"Nel curriculum scrivete quello che sapete fare... e anche quello che non sapete fare! Tipo: "Già vescovo di Cracovia, partecipai alla Coppa America, vincendola!""
[...]
"Sto giocando al piccolo Dio e mi sta venendo pure alla grande."
PM Quote
Avatar
lumo (Member)
Expert


Messaggi: 413
Iscritto: 18/04/2010

Segnala al moderatore
Postato alle 23:57
Sabato, 20/02/2016
È 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++

  1. 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.

PM Quote
Avatar
TheDarkJuster (Member)
Guru^2


Messaggi: 1452
Iscritto: 27/09/2013

Segnala al moderatore
Postato alle 1:14
Domenica, 21/02/2016
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.

PM Quote
Avatar
TheDarkJuster (Member)
Guru^2


Messaggi: 1452
Iscritto: 27/09/2013

Segnala al moderatore
Postato alle 1:25
Domenica, 21/02/2016
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++

  1. REFLECTABLE (     (const char *) name,     (int) age )


ottengo:
Codice sorgente - presumibilmente C++

  1. static const int fields_n = 2; friend struct reflector;



Ho commesso qualche errore in questo punto?

PM Quote
Avatar
lumo (Member)
Expert


Messaggi: 413
Iscritto: 18/04/2010

Segnala al moderatore
Postato alle 1:44
Domenica, 21/02/2016
Devi andare avanti, la parte essenziale è
Codice sorgente - presumibilmente Plain Text

  1. BOOST_PP_SEQ_FOR_EACH_I(REFLECT_EACH, data, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))


le cose usate qui sono definite sotto

PM Quote
Avatar
TheDarkJuster (Member)
Guru^2


Messaggi: 1452
Iscritto: 27/09/2013

Segnala al moderatore
Postato alle 15:07
Domenica, 21/02/2016
Ok... credo di aver capito: in pratica per ogni campo REFLECTABLE
Codice sorgente - presumibilmente C/C++

  1. template<int N, class Self>
  2. struct field_data {};



diventa l'espansione di
Codice sorgente - presumibilmente C++

  1. PAIR(x); \
  2. template<class Self> \
  3. struct field_data<i, Self> \
  4. { \
  5.     Self & self; \
  6.     field_data(Self & self) : self(self) {} \
  7.     \
  8.     typename make_const<Self, TYPEOF(x)>::type & get() \
  9.     { \
  10.         return self.STRIP(x); \
  11.     }\
  12.     typename boost::add_const<TYPEOF(x)>::type & get() const \
  13.     { \
  14.         return self.STRIP(x); \
  15.     }\
  16.     const char * name() const \
  17.     {\
  18.         return BOOST_PP_STRINGIZE(STRIP(x)); \
  19.     } \
  20. }; \



Ma è orribile e non mi permette di documentare le mie classi con doxygen. Quindi non posso usare questo metodo per la reflection..........

PM Quote