Newsgroup: it.comp.lang.c++
Titolo: Mission Impossible : espansione macro (con # stringizing) posticipata rispetto alla sostituzione template

Come da oggetto, mi chiedo se sia tecnicamente possibile, e se 
si, ovviamente, in che modo,
l'espansione di una macro (contenente l'operatore macro # 
stringizing che tramuta il simbolo ricevuto in un literal di 
tipo const char *) soltanto DOPO che sia stata effettuata la 
sostituzione di argomenti template in una specializzazione di 
oggetto template.
Ad es. se
#define STRINGIZE (AAA) # AAA
template <typename tt_Tipo> const char * Funzione (tt_Tipo 
Argomento)
{
.... codice
char * NomeStringaTipo = STRINGIZE (tt_Tipo);
return NomeStringaTipo;
}
Ebbene, mi compila, ma ogni istanza della funzione ritorna
"tt_Tipo" come nome literal, a prescindere dal tipo di dato 
effettivo della specializzazione.
Ho anche tantato di interporre vari livelli di macro "di 
ritardo", che non fanno altro che richiamarsi tra loro lasciando 
immodificato il parametro, o aggiungendo parentesi, o anche 
aggiungendo testo, ma col senno di poi trovo sempre che ogni 
livello di espansione macro PRECEDE la sostituzione template.
C'è il modo per aggirare, a compile time, questa priorità del 
preprocessore ? O meglio, c'è qualche opzione per 
post-processare il codice. Non so se ho chiesto in maniera giusta
ciao e grazie in anticipo
P.S. se qualcuno sa farlo, lo pregherei di spiegare la cosa in 
certo dettaglio e con pazienza, perché spesso ho dei problemi a 
visualizzare le fasi del preprocessore
riciao
Soviet_Mario

 Soviet_Mario
Ora non ho modo ne' tempo per provare, ma io farei:
#define STRINGIZE (AAA) # AAA
template <typename tt_Tipo, LPSTR tt_Name=STRINGIZE(tt_Tipo) > const 
char * Funzione (tt_Tipo Argomento)
{
  ..... codice
  char * NomeStringaTipo = tt_Name;
  return NomeStringaTipo;
}
se non funziona prova a non mettere il default e richiamare la funct cosi':
char * name = Funzione<pippo, STRINGIZE(pippo)>(pippo Argomento);
Ciao

 template in una specializzazione di oggetto template.
No, l'espansione delle macro avviene prima di qualsiasi analisi sintattica.
Ciao,
Nicola
-- 
Nicola.Musatti <at> gmail <dot> com
Home: 
http://nicola.musatti.googlepages.com/home
Blog: 
http://wthwdik.wordpress.com/

char * Funzione (tt_Tipo Argomento)
Ecco, scrivere una cosa del genere significa chiamarsi una saetta dal
cielo. Meritata.

visualizzare le fasi del preprocessore
Vedilo come un :
.c .h < preprocessore | compilatore > .o

Andrea Laforgia ha scritto:

domani provo a "bestemmiare", sono assai curioso a capire se 
funge o no, e in entrambi i casi la ragione
ciao
Soviet

logicMind ha scritto:

in effetti non conoscevo neppure i defaults negli argomenti macro
forse potrei aggirare con ulteriore livello di preprocessamento 
(data l'ora non ragiono bene)
template <typename tt_Tipo, char * tt_NomeStringaTipo> char * 
Funzione <tt_Tipo, tt_NomeStringaTipo> (pippo Argomento);
#define CREA_PROTOTIPO_FUNZIONE (Pippo) \
char * Funzione <pippo, STRINGIZE (pippo)> (pippo Argomento) { 
return tt_NomeStringaTipo; };
grazie infinite, comunque finisca la storia.
ciao
Soviet


Andrea Laforgia ha scritto:

:-( concordo

 
Non puņ nemmeno compilare. Se il parametro di un template č un puntatore,
gli unici valori consentiti sono istanze di puntatori con linkage esterno.
I letterali stringa non soddisfano questo requisito.
Max

 .c .h < preprocessore | compilatore > .o
volevi forse dire "preprocessore < .c. h | compilatore > .o" ?
-- 
Under construction

  }
Mah, credo che la cosa piu' semplice sia usare RTTI, questa credo sia
una delle poche cose che sa fare decentemente...
--*PaN!*
 
-- 
I'm using an evaluation license of nemo since 55 days.
You should really try it!
http://www.malcom-mac.com/nemo

 Azz, non conosco l'acronimo (o forse l'ho dimenticato).
RunTime Type Information.
EMG
--
EMAG Software Homepage:     
http://www.emagsoftware.it
The EMG's ZX-Spectrum Page: 
http://www.emagsoftware.it/spectrum
The Best of Spectrum Games: 
http://www.emagsoftware.it/tbosg
The EMG Music page:         
http://www.emagsoftware.it/emgmusic
 

 RunTime Type Information.
ah, ok grazie.
Ma si tratta di una classe di funzioni/servizi intrinseci al 
linguaggio (ossia standardizzati), o di facilities fornite da 
qualche libreria di terze parti ?
Nel secondo caso, ne esiste qualcuna semplice se non elementare 
e gratuita (meglio ancora open) che potresti segnalarmi ?
ciao
Soviet_Mario
P.S.
A parte tutto, trovo molto frustrante non riuscire ad aggirare 
in alcun modo il problema coi soli mezzi standard ! Uff


 terze parti ?
Che io sappia è standard, ma mi pare che non sia standard il formato con cui 
viene restituito il nome della classe. Quindi non lo puoi salvare e 
ripristinare in un'applicazione compilata con un diverso compilatore (o 
forse neanche con lo stesso, non lo so).


RTTI non mi è saltato fuori niente.
Immagino che tu sappia cos'è Google:
http://en.wikipedia.org/wiki/Run-time_type_information
In ogni caso, a me è servito fare uso della RTTI in pochissimi casi. 
Siccome è facile farsi prendere dall'entusiasmo ed abusarne, meno la
usi, meglio è.

 ciao e grazie in anticipo
Forse io e te abbiamo un problema simile. Io ho scelto di *non* usare
macro e sto vedendo come ce la si cava con MPL.
Ti avverto tuttavia che MPL non è per i deboli di cuore :)
Al momento il suo uso da parte del sottoscritto si aggira fra black
magic e voodoo magic. Ma se funziona, non parlerò più male del C++ (se
non per dire che accidenti se è difficile, in Python avrei già finito)
poichè il principale difetto di C++ sarebbe risolto dalla scoperta della
metaprogrammazione templatica.
-- 
blog:  
http://www.akropolix.net/rik0/blogs
 | Uccidete i filosofi,
site:  
http://www.akropolix.net/rik0/
      | tenetevi riso e
forum: 
http://www.akropolix.net/forum/
     | bacchette per voi.

 all'inizio del thread ?
Ah, si ce lo *avrei*. Peccato che non funge (cfr. altro thread). Per
cui...


 lausi, meglio č.
"Entusiasmo" non e' una parola che mi viene da abbinare a RTTI =)
L'unica cosa che e' in grado di fare decentemente e' tirar fuori un
nome (stringa) da un tipo, e mi sembra che fosse proprio quello che
l'OP volesse fare...
Per rispondere alla domanda originale:
template <typename tt_Tipo> std::string Funzione (tt_Tipo 
Argomento)
{
.... codice
std::string NomeStringaTipo = typeid(tt_Tipo).name();
return NomeStringaTipo;
}
Ho sostituito char * con string che mi parevano piu' appropriati (non
ricordo se .name() ritorni una string o un char *, nel dubbio ho
scelto la string che funziona sempre)
--
Marco
 
-- 
I'm using an evaluation license of nemo since 56 days.


 }
Come ti e' gia' stato detto la forma "canonica" sarebbe:
template <typename tt_Tipo> const char * Funzione (tt_Tipo
    Argomento)
{
    return typeid(Argomento).name();
}
Il problema e' che il nome restituito non e' standardizzato, ogni
compilatore fa a modo suo. Se ci spieghi a cosa ti serve magari
possiamo suggerirti strade alternative.
Ciao,
Nicola


 possiamo suggerirti strade alternative.
in realtà una cosa un po' fine a sé stessa : stavo facendo uno 
stack per oggetti generici di tipi qualsiasi, che ha una 
funzione di POP che verifica i tipi e, se non combaciano, 
ritorna un messaggio d'errore individualizzato con incluso il 
nome stringa del tipo atteso e di quello, incompatibile, richiesto.
Non so nemmeno se userò mai la cosa, ma volevo fare uno stack 
simile, ecco.
ciao
Soviet_Mario


 in realtà una cosa un po' fine a sé stessa : ...
In questo caso, ti consiglio di studiarti l'implementazione di 'boost::any'
e 'boost::any_cast'.
 
http://www.boost.org/doc/html/any.html
 
 
http://www.boost.org/doc/html/boost/any_cast.html
Max

Max M. ha scritto:

Cmq, ragazzi, e lo dico a tutti coloro che mi hanno dato il 
suggerimento, questa "type_id" è davvero un toccasana ! Per 
fortuna è implementata anche in VC++6_0 (che uso da battaglia), 
e ha un membro const char * name () che restituisce alcune (a 
volte curiose, traduzioni. Ad es. ho notato che dice
"char const *" se passo una stringa literal, e non "const char 
*", ma non è un dramma, basta che si capisca da solo.
Sul serio, mi avete dato una grossa dritta, e non ci sarei mai 
arrivato, perché non sospettavo minimamente l'esistenza di 
questo servizio intrinseco al linguaggio. Mi pare estremamente 
potente, anche se non l'ho ancora sfruttato.
ciao
soviet_mario

[...]questa "type_id" è davvero un toccasana ! 
Hmmm. Vedi di non guarire troppe volte. ;-)

 cui...
Adesso quasi funge. Manca un pezzetto, ma al momento non mi serve...
-- 
  Enrico Franchi (RiK0)
[ Yellow Dog Linux User ]
[ #299188 Linux Counter ]
[ MacOS X User          ]