|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Jan 2000
Messaggi: 551
|
STL: Farsi un fuctor iota sofisticato(Cionci ,Marco invited)
Mi sono accorto che la STL non ha nello standard il comodo functor iota implementato dalla SGI
(serve a generare sequenze di numeri in container tipo vector,list etc) quindi me ne sono fatto uno a mano.(Puo darsi che nella libreria boost ci sia già, ma sulla macchina di mio fratello non l'avevo a disposizione). Non esitate a proporre miglioramenti o segnalare anomalie (ve ne sarei grato) ![]() Codice:
template <class T> class iota_gen { public: iota_gen(T start,T increment) : current(start) ,inc(increment) {} T operator () () {T tmp= current; current+=inc; return tmp ;} private: T current; T inc; }; //Esempio di chiamata ... vector <double> viota(10); //riempie viota a partire da 0.0 aggiungendo 1.5 al precedente elemento generate(viota.begin(),viota.end(), iota_gen<double>(0.0,1.5)); ... (sottrazione,moltiplicazione,etc)per scegliere il modo in cui generare la sequenza e non limitarlo all'addizione. Siete capaci di farlo?Io al momento no. ![]() Non è un fatto necessario per me (al momento) ,ma mi sembrava un quesito interessante. ![]() Un esempio d'uso? suponete di avere la funzione x=f(y) non invertibile (o anche non facilmente invertibile). Voi avete bisogno invece di calcolare y=f(x) in un certo intervallo Xa -Xb . Un modo semplice è quello di approssimare y=f(x) con una poligonale. Quindi generate un vettore di n coordinate yi a partire da Ya con un intervallo (Ya-Yb)/(n-1); un altro vettore di n coordinate xi=f(yi). A questo punto potete calcolare qualunque valore Yc(Xc) sfruttando i punti a disposizione. Questo è il caso reale che è capitato a me ![]() |
![]() |
![]() |
![]() |
#2 | |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Re: STL: Farsi un fuctor iota sofisticato(Cionci ,Marco invi
Quote:
Codice:
#include <vector> #include <iostream> #include <algorithm> using namespace std; template <class T> class iota_gen { public: iota_gen(T start,T increment, T (*oper)(T cur, T inc) = default_op) : current(start) ,inc(increment), op(oper) {} T operator () () {T tmp = current; current = op(current, inc); return tmp;}; protected: virtual T default_op(T cur, T incr) {return cur+incr;}; private: T current; T inc; T (*op)(T st, T inc); }; template <class T> T molt(T current, T increment) { return current * increment; } vector <double> viota(10); ... generate(viota.begin(),viota.end(), iota_gen<double>(0.1,1.5,molt)); ... |
|
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Jan 2000
Messaggi: 551
|
Grazie Cionci
![]() avevo avuto l'idea dei puntatori ma non sapevo esattamente come farla. la tua è una ottima idea. La esamino meglio adesso. |
![]() |
![]() |
![]() |
#4 | |
Bannato
Iscritto dal: Nov 2002
Città: PV
Messaggi: 1210
|
Re: STL: Farsi un fuctor iota sofisticato(Cionci ,Marco invi
Quote:
Mi spieghi come funz?? E un puntatore a funzione vero? |
|
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3736
|
ma che cavolo di programma stai scrivendo???
![]() |
![]() |
![]() |
![]() |
#6 | |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Re: STL: Farsi un fuctor iota sofisticato(Cionci ,Marco invi
Quote:
T (*op)(T st, T inc); T è il valore di ritorno...op è il nome del puntatore (c'è * davanti perchè è un puntatore)...il resto sono i parametri... Non importa specificare i nome dei parametri formali (anzi non ha molto senso specificarli)... Meglio sarebbe scrivere così (anche io era da molto che non li usavo): T (*op)(T, T); In pratica op può accettare solo funzioni il cui tipo di ritorno è T e i parametri sono 2 di entrambi di tipo T... |
|
![]() |
![]() |
![]() |
#7 |
Senior Member
Iscritto dal: Jan 2000
Messaggi: 551
|
Dunque cionci,ieri ho fatto delle prove e
il compilatore mi segnala problemi solo quando lo chiamo senza specificare la funzione: generate(viota.begin(),viota.end(), iota_gen<double>(1.0 , 2.0)); (non so;dovrebbe per come ho capito,richiamare default_op ma mi segnala questo: Error E2034 riempvec.cpp 63: Cannot convert 'double (iota_gen<double>::*)(double,double)' to 'double (*)(double,double)' in function main() Error E2151 riempvec.cpp 63: Type mismatch in default value for parameter 'oper' in function main() ) Comunque le tue indicazioni sono state preziosissime e ti spiego perchè. 1)Ho capito che l'operazione da usare doveva essere memorizzata nella classe. 2)Volevo usare i functor standard e dopo una mezz'ora di tentativi assurdi in cui dichiaravo l'operazione come binary_function (non ti dico che usciva!) 3)Mi sono fermato a pensare,e ho concluso che plus divides etc in fondo non erano che degli oggetti(la cosa non mi era proprio chiarissima) quindi bisognava dichiararli e usarli (un'altra mezz'ora per concludere che dovevo metterli nel template ![]() Codice:
template <typename T ,typename TFOO> class iota_gen3 { public: iota_gen3(T start,T increment,TFOO tfo ) : current(start) ,inc(increment) ,foo(tfo) {} T operator () () {T tmp = current; current = foo(current, inc); return tmp;}; private: T current; T inc; TFOO foo; }; (perchè quando si tratta di template me ne vado subito e sempre nel pallone) Codice:
//Esempi di chiamata generate(viota.begin(),viota.end(), iota_gen3<double ,multiplies<double> >(1.0,2.0,multiplies<double>())); generate(viota.begin(),viota.end(), iota_gen3<double ,minus<double> >(10.0,1.0,minus<double>())); ![]() ![]() ![]() Vedi un pò tu se si può aggiustare qualcosa (la chiamata non è un esempio di leggibilità ![]() Comunque grazie per avermi fatto vedere come si usa un puntatore a funzione in una classe. Credo che l' 80 % del merito di iota_gen3 sia tuo. ![]() (Quanno ce vò ce vò ![]() A proposito: Chiamare una funzione tramite puntatore(a funzione) è + veloce rispetto ad una normale? Ps.scusate il papiello ![]() |
![]() |
![]() |
![]() |
#8 | |
Senior Member
Iscritto dal: Jan 2000
Messaggi: 551
|
Quote:
Sto scrivendo la mia tesi,questo codice mi è servito realmente(leggi sopra a cosa). La morale di verloc sulla STL: quando vedi per la prima certe funzioni,tu dici : "Daiiiii ... a chi puo fregare di queste str*****e ?" Poi arrivi ad incocciarle ![]() "Luke...non sottovalutare il lato oscuro della STL" ![]() |
|
![]() |
![]() |
![]() |
#9 |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Bene
![]() Riguardo alla velocità... Direi proprio di no... Visto che bisogna andare ad accedere in memoria per recuperare l'indirizzo della funzione che altrimenti sarebbe calcolato automaticamente in fase di compilazione... |
![]() |
![]() |
![]() |
#10 |
Bannato
Iscritto dal: Jul 2000
Città: Malo (VI)
Messaggi: 1000
|
Vedo che avete gia' fatto tutto voi
![]() Solo un paio di piccoli suggerimenti per la leggibilita'. La prima e' quella di aggiungere un parametro di default per l'oggetto da utilizzare, Codice:
template <typename T ,typename TFOO> class iota_gen3 { public: iota_gen3(T start,T increment,TFOO tfo [b]=TFOO()[/b] ) : current(start) ,inc(increment) ,foo(tfo) {} Codice:
//Esempi di chiamata generate(viota.begin(),viota.end(), iota_gen3<double ,multiplies<double> >(1.0,2.0)); generate(viota.begin(),viota.end(), iota_gen3<double ,minus<double> >(10.0,1.0)); Codice:
template <typename T , typename TFOO> iota_gen3<T,TFOO> mk_iota( T x , T y , TFOO z ) { return iota_gen3<T,TFOO>(x,y,z); } Codice:
generate(viota.begin(),viota.end(), mk_iota(1.0,2.0, multiplies<double>() )); Codice:
multiplies<double> mul; generate(viota.begin(),viota.end(), mk_iota(1.0,2.0,mul )); |
![]() |
![]() |
![]() |
#11 |
Senior Member
Iscritto dal: Jan 2000
Messaggi: 551
|
Semplicemente Meraviglioso,Marco!
Non scherzo se dico che tu e Cionci date delle botte di progresso enormi alle mie conoscenze di apprendista. Sul serio,credetimi! E' riconoscenza,non piaggeria! Mercì ![]() |
![]() |
![]() |
![]() |
#12 |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
E' /\/\@®¢Ø il mago della STL
![]() ![]() |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 17:25.