Newsgroup: it.comp.lang.c++
Titolo: closure

funzione, perche' c.g non e' qualcosa di utilizzabile?
Scusate se riprendo un post così vecchio ma mi interessa molto
l'argomento e non si era arrivati ad una vera conclusione. Alla fine
quale è secondo il metodo migliore (per velocità, per occupazione di
memoria e per portabilità) per ottenere una closure in C++?
-- 
Marco Barisione (ICQ 84277092)

 memoria e per portabilità) per ottenere una closure in C++?
Adottare bcc come standard? :-)
Scherzi a parte, io ho la sensazione che il supporto in termini di
linguaggio base risulterebbe la soluzione piu' semplice e versatile, per
quanto non sia sicuro di comprendere tutti i dettagli. Il problema che
vedo nell'impiego di soluzioni a livello di libreria e' che il C++ rende
difficoltoso "perdere" informazioni di tipo, come succede
nell'implementazione Borland quando assegno ad una closure:
(sintassi inventata)
struct C { int f(double d) { return d; } };
C c;
int __closure(double) myClosure = c.f;  
il tipo di c e' scomparso (e quindi anche int (C::*)(double) ). Questo
si puo' ottenere solo con il polimorfismo (codice non compilato):
template <typename Ret, Typename Arg> class Closure {
  public:
    virtual Ret operator() (Arg a) = 0;
    virtual ~Closure() {}
};
template <typename C, typename Ret, Typename Arg> class ClassClosure :
	public Closure<Ret,Arg> {
  public:
    typedef Ret (C::* Method)(Arg);
    ClassClosure() : m(0), o(0) {}
    ClassClosure(C * cc, Method mm) : c(cc),m(mm) {}
    Ret operator() (Arg a) { return c->*m(a); }
  private:
    C * c;
    Method m;
};
Questo andrebbe usato come:
Closure<int,double> & cl = ClassClosure<C,int,double>(c,&C::f);
Direi che non c'e' paragone. Se poi vogliamo mantenere la semantica di
valore propria delle closure, non c'e' che adottare una tecnica
handle/body: sempre peggio...
Ciao,
Nicola

[...]
Ti spiego meglio quale č il mio problema.
Avrei voglia di scrivere un interprete per un mio linguaggio in C++,
probabilmente non lo realizzerň mai ma anche se lo facessi sarebbe
ovviamente molto semplice e con performance pessime, ma lo faccio
giusto per gioco.
Avevo pensato all'utilizzo delle std::map in cui ad una stringa
collego un oggetto. Avrei cosě in ogni oggetto una map che indica gli
attributi, un po' come fa python. Non so se mi sono spiegato
decentemente ma spero che capiate.
Se io nel mio linguaggio ho una stringa come questa:
nome_oggetto.foo()
l'interprete deve recuperare da qualche parte l'oggetto che si chiama
nome_oggetto e poi guardare se nel dizionario di quell'oggetto c'č
"foo", se c'č si richiama la funzione corrispondente.
Il mio problema č che vorrei che alla stringa possa corrispondere
indifferentemente un metodo od una funzione.


 indifferentemente un metodo od una funzione.
Su "Modern C++ Design" A. Alexandrescu descrive un "funtore
generalizzato", che rende uniforme la rappresentazione di tutte le
entita' "chiamabili".
Ciao,
Nicola

entita' "chiamabili".
E tu mi faresti comprare un libro apposta? :-(
Potresti darmi solo qualche indicazione? E` qualcosa di molto
complicato?




No, il libro te lo faccio comprare perche' e' un ottimo libro. In ogni
caso il punto di partenza e' sostanzialmente l'esempio che ti ho postato
qualche messaggio fa; a questo dovresti aggiungere altre sottoclassi per
gestire le funzioni libere ed eventualmente gli oggetti funzionali.
Se poi vuoi avere una closure canonica, ovvero assegnabile ecc., devi
avvolgere il tutto in una classe esterna che deleghi ad un istanza di
Closure allocata dinamicamente. Semplice, no? :-)
Ciao,
Nicola

Closure allocata dinamicamente. Semplice, no? :-)
Semplicissimo! :-)
