Newsgroup: it.comp.lang.c++
Titolo: puntatore ad istanza di classe template

sicuramente se ne è già parlato e probabilmente avevo salvato i 
post ma per qualche arcano motivo, non riesco a ritrovare 
proprio quelli che mi servirebbbero, per cui riposto la domanda.
Ho due classi template (i cui argomenti template sono estranei 
tra loro), e le classi pure sono indipendenti
template <unsigned MaxNumArmoniche> class ClsStrumento
{
ClsArmonica Arms [MaxNumArmoniche];
//etc etc
}
template <unsigned MaxNumStrumenti> class ClsOrchestra
{
ClsStrumento <...> * PtrListaStrumenti;
}
Ovviamente ClsStrumento <...> non è una dichiarazione valida, è 
solo per far capire cosa mi servirebbe.
il problema è appunto che NON vorrei che la classe orchestra 
ricevesse l'argomento templante dell'oggetto incluso per poterne 
   linkare di tipi diversi (tutti però di tipo affine, 
ClsStrumento, e tutti template, ma ciascuno con dimensioni 
differenti, per il resto avendo interfaccia identica).
Quindi dentro ClsOrchestra mi servirebbe un puntatore generico 
ad una qualsiasi istanza di tipo ClsStrumento<...> e non a un 
tipo specifico completamente definito. Un tipo incompleto, 
diciamo, non so se si possa chiamare così.
Come si dichiarava o come si aggirava il problema ? Mi sembra di 
ricordare che qualcuno me lo avesse già detto (il guaio è non 
che non salvo le cose, ma che ne salvo troppe :-( e poi non le 
ritrovo).
ciao e grazie in ancicipo
Soviet

 diciamo, non so se si possa chiamare così.
I tipi incompleti sono tipi dichiarati ma non (ancora) definiti. Non hanno
niente di generico.
Max

 I tipi incompleti sono tipi dichiarati ma non (ancora) definiti. 
si, questa è l'accezione corretta della terminologia. MA l'avevo 
usata per dire una cosa diversa, probably non esistente. Ossia 
volevo usare un tipo incompleto (azz !)
ciao
Soviet


 completamente definito. 
Non ho capito come mai non metti un altro parametro al template 
ClsOrchestra che specifichi il tipo di ClsStrumento da utilizzare.
E.

class ClsArmonica
{
    //etc etc
};
template <unsigned MaxNumArmoniche>
class ClsStrumento
{
    ClsArmonica Arms [MaxNumArmoniche];
    //etc etc
};
template <unsigned MaxNumStrumenti, unsigned MaxNumArmoniche>
class ClsOrchestra
{
    ClsStrumento <MaxNumArmoniche> * PtrListaStrumenti;
};
int main( )
{
    ClsOrchestra<2, 3> orchestra;
}
Spero di essere stato di aiuto.
Ciao.
Soviet_Mario ha scritto:


 Ciao.
ti ringrazio, ma è una soluzione che mi andrebbe molto stretta, 
per i motivi che ho cercato di esporre a <?Manu*> nell'altro 
post di poco fa. Se hai voglia, prova a leggerlo, e se ti è di 
ispirazione ... beh, aspetto altri hint
ciao
Soviet
CUT ALL

puntatore alla base StrumentoGenerico, no ?
#include <iostream>
#include <vector>
class CArmonica {
public:
  CArmonica() {
  	 std::cout << "costruito CArmonica" 
                  << std::endl; 
  } 	 	         	
};
typedef std::vector<CArmonica>::size_type VSize;
class CStrumento {
public:
  virtual void suona() = 0;
};
template <VSize maxArmoniche> class CStrumentoArmonico: public
CStrumento {
public:
  CStrumentoArmonico() { 
  	  for (VSize i=0; i != maxArmoniche; i++) 
  	    v.push_back(CArmonica());
 
  	  std::cout << "costruito CStrumentoArmonico<" 
  	            << maxArmoniche 
  	            << ">" 
  	            << std::endl;
  }
  void suona() {
  	  std::cout << "CStrumentoArmonico<" 
  	            << maxArmoniche 
  	            << "> suona allegramente!" 
  	            << std::endl;
  }
private:	
  std::vector<CArmonica> v;  
};
int main() {
	CStrumento *pS1 = new CStrumentoArmonico<2>();
	CStrumento *pS2 = new CStrumentoArmonico<5>();
 
	pS1->suona();
	pS2->suona();
}
Ha l'output seguente:
costruito CArmonica
costruito CArmonica
costruito CStrumentoArmonico<2>
costruito CArmonica
costruito CArmonica
costruito CArmonica
costruito CArmonica
costruito CArmonica
costruito CStrumentoArmonico<5>
CStrumentoArmonico<2> suona allegramente!
CStrumentoArmonico<5> suona allegramente!

 
Ok : quindi è la strategia della classe base non template come 
membro virtuale delle varie classi specializzate "sorelle" (tipi 
generati dal template).
Devo studiarmi bene la soluzione.
grazie dei consigli
ciao
Soviet


generati dal template).
Non è una strategia particolare, è quella di sempre, della derivazione
e del polimorfismo.  

ClsOrchestra che specifichi il tipo di ClsStrumento da utilizzare.
A me sembra che non sia corretto. Un'orchestra è un'aggregazione di
strumenti, mentre aggiungere un parametro al template significa
realizzare un nuovo tipo orchestra strettamente legato a uno
strumento... a che pro?


Beh, io non ho cercato di estrapolare il significato dai nomi delle 
variabili... in tal caso non capisco il senso di parametrizzare un 
template per lo strumento con il numero massimo di armoniche... Cosa 
significa avere uno strumento che ha un massimo di 10 armoniche? E 
perché dovrei definire due orchestre, una con un numero massimo di 100 
strumenti e una con un numero massimo di 1000 strumenti?
E.

Cosa significa avere uno strumento che ha un massimo di 10 armoniche?
Non so, ma ho già ammesso la mia ignoranza musicale :-)

 e del polimorfismo.  
Si, hai ragione. Ma non avevo mai visto questa parentela tra 
tipi template e non misti, diciamo.
ciao
Soviet_Mario

 parametrizzato
Non confondere.
Quanto detto da me non riguarda la natura della classe: template o
meno.
Dal mio punto di vista, non ha senso il parametro template sul massimo
numero d'armoniche, basta passare un valore al costruttore della
classe.
<snip sul resto, che con tutto il rispetto, mi sembrano
sciocchezze ;-)>

 vorrei sovradimensionare tutti quanti.
Dunque utilizzeresti una diversa classe per ogni diverso strumento, in 
base al numero di armoniche? Non sarebbe possibile avere una funzione 
che agisce su uno strumento generico.
E.

 }
Si conosce a compile-time il tipo dell'n-esimo elemento di tale lista?
Se la risposta è no (come probabile), quello che chiedi è chiaramente 
impossibile.
E comunque stai andando contro il concetto di OOP.
Se gli strumenti sono completamente diversi, allora non sono strumenti.
In cosa consistono queste differenze? Isola tali differenze e costruisci 
una gerarchia di classi.
Con i template e le macro ho fatto, per gioco, veramente di tutto, ma 
nel codice reale cerco di evitarne ogni *abuso*.
Ci sono comunque eccezioni. Per esempio ho un file di 10000 righe di una 
complessità enorme che mi genera codice ad hoc per la pipeline di un 
motore grafico. Ma l'alternativa sarebbe stata ben peggiore!
Già che ci siamo, penso che le librerie Boost costituiscano un buon 
esempio di quello che non bisognerebbe mai fare. Quando una cosa 
semplicissima in un linguaggio X richiede codice di grandissima 
complessità in un linguaggio Y, allora qualcosa non va. Perché dovrei 
usare una libreria complicatissima e che mi sputa fuori messaggi 
d'errore di 1000 righe assolutamente incomprensibili quando posso farmi 
un programma in C++ perfettamente portabile che fa tutto ciò che mi 
serve in modo veloce e semplice? In 2 sec. lo integro nell'IDE e 
chiunque può fare lo stesso su qualsiasi piattaforma.
Tornando al tuo codice, perché usi "ClsArmonica Arms [MaxNumArmoniche];" 
quando potresti tranquillamente usare un vettore da inizializzare alla 
giusta dimensione tramite costruttore? Vale la pena complicarsi la vita 
di 1000 volte per evitare un'allocazione dinamica?
Hai veramente verificato che questa costituirebbe un collo di bottiglia 
per il tuo programma?
Kiuhnm

serve in modo veloce e semplice? 
A parte che il concetto di "complicatissimo" e "incomprensibile" ha un
valore del tutto personale, l'idea di libreria è proprio quella di
racchiudere un insieme di "utility". E' banale persino dirlo. 
O forse tu riscrivi tutte le volte il codice che ti serve?  E sei
sicuro di saperlo fare bene quanto altri?

 sicuro di saperlo fare bene quanto altri?
Non uso mai librerie (se non posso proprio fare altrimenti) di cui non 
ho il codice sorgente. Ispeziono il codice e se ritengo che sia 
difficile da estendere o mantenere, evito la libreria.
Tu che parli tanto, hai studiato il codice delle librerie Boost? Ti sei 
fatto una nuotata nel mondo della "metaprogrammazione"? Non credo 
proprio, altrimenti non parleresti così.
La "metaprogrammazione C++" è inelegante, innaturale e poco più di una 
curiosità. Urge una completa risistemazione affinché possa considerarsi 
un valido strumento.
Kiuhnm

un valido strumento.
Accidenti, l'e-mail al comitato ISO l'hai già spedita?

 pensare che non abbia esperienza, caro sconosciutissimo Kiuhnm.
Ok, finiamola qui. Ho ben altro da fare.
Kiuhnm

 sciocchezze ;-)>
non ho colto bene il tenore di questo commento finale. Io ho 
descritto alcune esigenze e cerco di risolverne alcune. Se non 
ti interessano o ti sembrano sciocchezze, non rispondermi e 
stop, punto.
ciao
Soviet

 Kiuhnm

 fread (handle, & StrumentoPiccolo, sizeof(StrumentoPiccolo), 1);
Questa tua idea mi sembra molto strana. Che senso ha leggere gli 
strumenti dal file, sapendo A PRIORI la size di ogni strumento? E' 
l'obiezione che ti abbiamo fatto altrove sia io che Kiuhm. Tantovale 
codificare lo strumento direttamente nei sorgenti.
E.

 che scrivo, la funzione SUONA la codifico una tantum e poi se la vede lui.
Prima o poi anche la funzione template va specializzata. In particolare 
nel tuo codice devi decidere, staticamente, quali sono i parametri del 
template che utilizzi. Questi risulteranno essere fissati, non possono 
dipendere dall'input (i.e. nè puoi leggerli da file).
E.

 Il Vector rispecchia questo ?
Sě, fidati. Se vuoi una serializzazione brutale con fwrite puoi fare 
qualcosa del tipo:
vector<T> v;
FILE *fp;
....
size_t s=v.size();
fwrite(fp,&s,sizeof(size_t));  // scrivi la dimensione del vettore
fwrite(fp,&v[0],sizeof(T)*s);  // scrivi tutto il contenuto
Osserva che anche utilizzando gli array dovrai scrivere da qualche parte 
la dimensione effettiva dell'array, non te la puoi cavare senza.
E.

 stop, punto.
Oppure risponderti e dire che, per me, sono sciocchezze. Perché vuoi
censurare le opinioni?

 Ok, finiamola qui. Ho ben altro da fare.
LOL... c'avrei scommesso :-)

 informazione e un modo efficace di venire incontro a certe esigenze.
Per dire, a me i template piacciono molto poco. Tempi di compilazione 
molto lunghi, codici di errori incomprensibili, debug difficoltoso, e 
cosa peggiore, molte persone le usano a sproposito.
E' dal 2005 che ho ereditato del codice in cui tutto è un template. 
Elegante dal punto di vista matematico, ma stupido nel mondo reale di 
quel tipo di applicazione. Piano piano sto eliminando i template, e lo 
faccio sono per non metterci 15 minuti ad ogni compilazione. Perchè, 
come programmatore, mi capida di modificare il codice, e modificarlo 
negli header è palesemente micidiale.
Ogni linguaggio è pieno di splendide trovate, in python come in C# per 
esempio hanno messo la decorazione dei nomi delle funzione. Ho visto 
varie persone che usano la decorazione invece dei parametri, che 
evidentemente ritengono una cosa "vecchia".
Personalmente ritengo la metaprogrammazione una grande trovata, ma come 
per tutte le cose va usata se serve. Non parlo per te, che non conosco, 
però vedo un sacco di persone che fa scelte a caso. Un tempo ero anche 
io così, ma l'esperienza aiuta un bel po'
Pensa un po' che io apro i file ancora con i descrittori FILE. Mi trovo 
bene, non ho problemi, e uso una semantica identica a quella che uso 
quanto faccio qualcosa in python. Il fatto di non essere un purista del 
C++ non mi preoccupa molto. A me rompe di più le balle non sapere che 
"std::endl" se inserirà il carattere '\n' o la stringa "\r\n" come fine 
riga. Quello che per uno è una cosa comoda, per un altro è una 
seccatura.
-- 
la cultura è importante: 
http://www.libreriadellautomobile.it

 C++ non mi preoccupa molto.
Non si tratta, in realtà, di essere puristi, ma di approfittare di ciò
che di buono offre questo linguaggio.  Poi, tra approfittare ed
abusare c'è una bella differenza :-)

 quel tipo di applicazione.
Allora dubito che sia "elegante" dal punto di vista matematico, per come 
l'intendo io. La matematica č chiarezza e sintesi. L'uso dei template 
per la metaprogrammazione ricorda invece l'uso di uno scolapasta per 
trasportare sabbia da un luogo all'altro.
Quasi quasi lo considererei "hacking", cioč piegare un "meccanismo" al 
proprio volere utilizzandolo in modo inaspettati e geniali.
I template del C++ hanno sicuramente aperto la via, ma adesso andrebbero 
rivisti. Gli stessi tempi di compilazione elevatissimi (di cui parli piů 
avanti) indicano che l'approccio non č quello giusto.
Kiuhnm

 Il Vector rispecchia questo ?
Allora dovresti limitarti all'uso dei POD.
Sinceramente non ci vedo alcun vantaggio. Chi ha detto che un oggetto 
per essere serializzato debba contenere tutti i dati in memoria 
contigua? Un albero non lo serializzi? Percorri i nodi ricorsivamente e 
li salvi uno a uno, no?
Kiuhnm

 censurare le opinioni?
censurare ? Mah, non l'ho fatto. Dico solo che a volte scrivi 
(non che sei, perché in rete traspare solo una immagine parziale 
di una persona) con tronfia arroganza. Che poi tu sappia molto 
bene il linguaggio e sia un ottimo programmatore, su questo non 
sta a me dirlo, ma non mi capita frequentemente di leggere post 
altrui, anche di altri esperti programmatori del NG, che 
esprimono facilmente giudizi supponenti. C'avrai i tuoi motivi 
per essere nervoso, boh. Non è un mio problema cmq.
ciao
Soviet

 Kiuhnm

 sparso per fare una sorta di shallow-copy in un unico accesso da/a disco.
Il vector è molto poco sparso, è formato da due pezzi.
E.

 Ma se scrivo da fuori il suo contenitore,
Potresti spiegare meglio cosa tu intenda con "scrivo da fuori il suo
contenitore"?
Ciao.
-- 
BSD is for UNIX lovers -- linux is for Windows haters.

 Il Vector rispecchia questo ?
Dipende da cosa tu intenda con self-contained.


 Per il resto, se hai qualche altra idea, grazie in anticipo
Penso di parlare per (quasi) tutti se dico che in definitiva non si 
capisce che cosa vuoi fare. Dovresti cercare di definire chiaramente 
obiettivo e restrizioni a prescindere da concetti estranei al C++ 
(armoniche, strumenti, ecc...). Altrimenti mi pare di sparare alla cieca.
Inoltre non puoi pretendere che io mi legga l'intero thread a caccia di 
informazioni extra :-)
Kiuhnm

 è un oggetto sparso.
Sinceramente questo modo di vedere una matrice sparsa mi è totalmente
nuovo, e non è certamente quello comunemente conosciuto.
Una matrice sparsa è una matrice nella quale la maggior parte degli
elementi è zero.
Sparso sta per "non denso", non per "sparpagliato".
Ciao.
-- 
BSD is for UNIX lovers -- linux is for Windows haters.

 indici, tipico da array.
Il vector non è una lista. Ha accesso diretto tramite indici come gli 
array.
E.

 elementi è zero.
Ovvero gli elementi non nulli sono ... sparsi.
Kiuhnm

 abbia rinunciato.
Hai letto gli standard di entrambi i linguaggi prima di dirlo?
Ti abbandono Soviet_Mario, non aggiungerò altri interventi, perché la
discussione è diventata abbastanza sterile.
Buona program... ahem... buona chimica ;-)

 c'è chi usa il C++ a sproposito.
In questo senso il C++ è tremendo. Presuppone che tu sappia quel che 
fai, e non ti rompe le balle con gli "aiutini". Altro che l'IDE del VB 
(che per molti è il linguaggio) che ti corregge la sintassi. Un poco 
come guidare una macchina da corsa. Detto questo per andare a fare la 
spesa una una macchina normale.
Oppure tradotto, per i server che devono macinare 1 gb di roba al 
giorno preferisco il c++ sempre, per i programma più o meno usa e getta 
indifferentemente c#, cpp, python (dipende da cosa devo fare).
Ma sono mie paranoie. Mi capita a volte di scrivere codice portabile 
linux e windows, e devo ammettere che python è un'altra storia. Mi è 
capitato di scrivere un programma mission critical in python. Ci ho 
messo un decimo del tempo che in C/C++.
Io odio profondamente le GC perché non riesco a controllarne il 
comportamento e il consumo di memoria, e per questo non userò mai  
"sistemi" che praticamente me la impongano.


 Ci riprovo, per dimostrare la buona fede.
Scusa, io invece ci rinuncio... Penso che avrai delle sorprese quando 
farai l'implementazione, ma č una mia opinione personale.
E.

 Buona program... ahem... buona chimica ;-)
anche l'ironia è un ingrediente che va dosato con parsimonia, cmq
ciao
Soviet_Mario

 chiamare così.
Ecco la dichiarazione di un puntatore generico:
   void * PtrListaStrumenti;
Con un cast lo puoi far diventare puntatore a qualunque cosa (tranne che 
a un membro).
D'altra parte, ClsStrumento<1> e ClsStrumento<2> sono due tipi diversi.
Non puoi avere un puntatore di tipo diverso da "void *" che possa 
puntare a oggetti di entrambi i tipi.
-- 
     Carlo Milanesi
 
http://digilander.libero.it/carlmila

 sabbia da un luogo all'altro.
Ci ho pensato a lungo, però mi viene il dubbio che la tua sia una 
posizione impostata male. Ho l'impressione che se io, con i miei 
limiti, seguissi i tuoi ragionamenti logici arriverei alla conclusione 
che le classi sono una grande cagata.
Spesso vedo ramificazioni folli, profondissime, in gerarchie di classi. 
Talmente folli che non si capisce nulla. Qualsiasi sputacchio ha la sua 
classe. Niente ortogonalità, quando potrebbe esserci, nessuna chiarezza 
evidente in chi ha costruito la gerarchia. Mi è capitato spesso di 
vedere che considerano il compitino che gli è stato assegnato con un 
progetto dalla complessità degna di un db Oracle.
Sarà una banalità, ma se uno non ha l'idee chiare sul problema che deve 
affrontare, non conosce bene il linguaggio, e infine non ha esperienza 
sul campo di tutto il ciclo vitale del software (installazione e 
manutenzione dal cliente), non può che scrivere software mediocre (geni 
a parte). In questi casi i template non sono che un ulteriore mezzo per 
farsi del male. Ancora oggi mi trovo a maneggiare delle macro altrui 
lunghe 20 righe. Io mi domando, ma fare una funzione era così brutto?
Insomma, ho paura che confondi lo strumento con l'utilizzo. Fosse anche 
uno strumento spuntato come dici, in mano ad un bravo programmatore non 
farebbe danni.
Sulla boost per altro siamo della stessa opinione. In alcuni punti 
hanno forzato troppo l'uso dei template, anche quando non serve.


 puntare a oggetti di entrambi i tipi.
Mi sono orientato, come suggeritomi inizialmente proprio da 
LaForgia, verso la creazione di una classe base astratta 
definita StrumentoGenerico, che ogni tipo template 
Strumento<NumArm> deve implementare (nel senso almeno 
dell'interfaccia minima utile dall'esterno e dai contenitori di 
Strumenti, Orchestra ed altri).
A proposito della lista delle armoniche allocata come array 
fisso interno dei tipi di Strumento<...> specifici, faccio in 
modo che nei costruttori di costoro venga inizializzato anche un 
generico puntatore "Armonica * ptrListArmoniche" e un contatore 
"int ArmNumReserved", presenti nel tipo base StrumentoGenerico, 
che NON vengono mai inizializzati da nessun costruttore di codesto.
Non so se sia una pensata esente da rischi (quello di 
re-inizializzare a valori validi alcuni membri del tipo base 
solo dentro il costruttore di un tipo derivato da esso, che di 
fatto riserva lo spazio fisico reale per il tipo base). Non ho 
trovato di meglio e ho pensato che se tanto StrumentoGenerico è 
astratto, non potrà di fatto essere creata e usata nessuna 
istanza in uno stato non valido (con il puntatore nullo 
"Armonica * ptrListArmoniche").
Da quali altri rischi dovrei eventualmente dovermi guardare con 
un simile approccio ?
ciao
Soviet_Mario


Così sembra quasi che l'abbia scritto io...
Kiuhnm

 }
Visto che non demordi, puoi procedere cosě:
1) Definisci la classe ClsStrumento senza array.
2) Allochi un array (rawArray) di ClsArmonica in grado di contenere la 
classe ClsStrumento seguita da un array di MaxNumArmoniche ClsArmonica.
3) Determini l'indirizzo (arrayAddr) d'inizio dell'array di 
MaxNumArmoniche ClsArmonica.
4) Costruisci la classe ClsStrumento all'inizio di rawArray, passandole 
arrayAddr tramite costruttore.
Se vuoi puoi implementare un operator[] in ClsStrumento che acceda 
correttamente all'array usando arrayAddr.
Kiuhnm

 arrayAddr tramite costruttore.
sarebbe il cosiddetto "new with placement", vero ? E' una idea 
molto flessibile, in effetti.
Ma come funge delete in questi casi ? Bisogna implementarlo ?
ciao & tnx
Soviet_Mario


 Ma come funge delete in questi casi ? Bisogna implementarlo ?
Devi distruggere quello che hai costruito e quindi deallocare quello che 
hai allocato.
Nel tuo caso chiami i distruttori per gli oggetti costruiti con la 
placement new e quindi liberi rawArray con "delete[] rawArray".
Lascio a te i dettagli.
Kiuhnm

 servisse.
Puoi usare gli iteratori anche su un array. In particolare i vari
algorirmi generici che usano gli iteratori funzionano su un array come
su un vector.
-- 
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.

 DENTRO all'oggetto sparso stesso
Un vector comunque è contiguo. Leggi sullo stroustrup, dovrebbe essere
precisamente un requisito. O sullo standard.


 cose ?
Questa è una frase abbastanza discutibile e privo di senso: sul 'quello
che puoi farci', la risposta è no. Esattamente come invece che in C
potrei farlo in Pascal. Per dire.
Sul fatto che i linguaggi *non* sono l'uno un sopra-insieme dell'altro
però ha ragione Andrea.
C89 non era un sottoinsieme di C++. Per esserlo sarebbe dovuta valere la
proprietà che ogni programma C89 valido, compilato come programma C++,
avesse senso e avesse la stessa semantica. Questo non è vero per alcuni
motivo.
Adesso con C99 addirittura la cosa è falsa. Un esempio banale:
int foo(int n){
  int bar[n];
  ....
}
è codice C99 valido, standard e perfettamente accettabile. In C++ quel
codice non è valido. Devi ricorrere all'estensione di qualche
compilatore.


 Kiuhnm

 compile-time.
Ma perdi il fatto di modellare facilmente che arriva $GrandeSolista e si
aggiunge all'orchestra.


 dopo avere distrutto l'ultimo ClsStrumento al suo interno ?
In ogni rawArray dovrebbe esserci un solo ClsStrumento seguito da un array.
Un dettaglio mancante: non dovresti far costruire i ClsArmonica dalla 
new quando allochi rawArray perché quelli iniziali verrebbero 
sovrascritti da ClsStrumento prima di essere distrutti.
Vedi il mio post passato oppure cerca in rete.
Kiuhnm

 optimization. Sai cosa diceva il grande Knuth a riguardo?
Beh, non lasciarci sulle spine... cosa diceva Knuth? (anzi, cosa dice, 
visto che è vivo)
E.

 Cosě sembra quasi che l'abbia scritto io...
Ops, dovevo cancellare la riga col tuo nome...
E.

 Kiuhnm
ciau
Soviet_Mario

 visto che è vivo)
Si, ma la cosa la aveva detta tempo fa:
We should forget about small efficiencies, say about 97% of the time:
premature optimization is the root of all evil.
In buona sostanza le persone ottimizzando fanno spesso errori. In primo
luogo spesso il programmatore sbaglia a vedere ad occhio le fonti di
inefficienza. Ci sono cose che uno potrebbe vedere banalmente come
inefficienti, ma senza sapere che il compilatore é perfettamente in
grado di ottimizzarle.
In particolare per vedere ad occhio quali sono i problemi (senza usare
tools di profiling, etc) bisogna avere *molto* occhio. E anche cosí si
sbaglia. IMHO é meglio usare gli appositi tools. 
A quel punto, avendo individuato le cause di lentezza, si puó
ottimizzare con cognizione di causa, senza avere giá 'sporcato e reso
poco mantenibile' il codice.
L'unica ottimizzazione da fare prematuramente (ma in realtá é
semplicemente fatta al momento giusto) é quella che riguarda il design
del software a 'livello macroscopico'. Un buon design e' vitale.
Ma il resto no. Peraltro usare i buoni crismi di programmazione OOP ha
precisamente il vantagio che si possono cambiare dettagli implementativi
con poca fatica. Per esempio passare dal vector all'array. Se e solo se
é necessario.
Inoltre si fa sempre presto a sporcare il codice per spremere tutti i
cicli di clock. E' il contrario che e' quasi impossibile.


 cicli di clock. E' il contrario che e' quasi impossibile.
ciao
Soviet

 premature optimization is the root of all evil.
Un'altra cosa da tenere a mente è che ci vuole il giusto equilibrio tra 
qualità e tempo di produzione. Se la qualità è troppo bassa, il progetto 
fallisce; se la qualità è troppo alta il progetto non giunge mai a 
compimento. In proposito c'era un articolo...
Kiuhnm

 compimento. In proposito c'era un articolo...
Piu' di uno. Io personalmente ho ben presente quello che scrive Beck sul
suo testo: ovvero che la qualita' non e' normalmente una variabile in
gioco: piu' di tanto non la si puo' fare variare (senza appunto avere le
conseguenze che delinei).


 accessi al file.
Io non sono per nulla convinto che questo sia davvero un vantaggio:
primo perchè hai detto più volte di non avere studiato a fondo vector e
altre strutture dati, per cui non sai davvero come funzionano.
In secondo luogo se tieni conto di come funzionano I/O nell'OS
sottostante, vedi che anche se per fare il marshalling di una struttura
dati devi 'rincorrere' dei pezzi, *comunque* l'OS sottostante fa del
buffering. Per cui non hai davvero un problema di performance. Se lo
avessi puoi sempre serializzare in RAM e poi scrivere la cosa
serializzata.
Insomma, puoi avere mille strategie a riguardo. E a me sembra che
limitarsi ad un tipo di dato (con cui fai x operazioni) perchè in una
delle x operazioni *pensi* che questo ti dia migliori performance, sia
un errore di design.
Inoltre non vorrei essere io a dirlo: ma spesso le persone che scrivono
un OS sanno *parecchio* come ottimizzare le cose (perchè hanno un'ottima
conoscenza dell'OS stesso). I programmatori che pensano di usare
strategie particolarmente furbe non necessariamente fanno una cosa
buona: capita spesso che queste strategie finiscano per litigare con
l'OS sottostante, dando performance peggiori.
Quindi ancora una volta la scelta giusta è tenere le due cose separate:
da un lato le classi. Puoi facilmente cambiare la strategia di
serializzazione indipendentemente da come sono memorizzate le classi. 
Se ancora non sei convinto, mi metto nella fila di quelli che ci hanno
rinunciato.


 algoritmi.
Sì, sapeva programmare. Quando ha cominciato a scrivere la serie "The 
Art..." negli anni '70, si è reso conto che gli strumenti informatici 
per gli autori non erano adeguati. Quindi ha deciso di scrivere un 
programma per l'impaginazione (TeX, tutt'oggi largamente usato). Per 
scrivere questo programma ha inventato un nuovo linguaggio di 
programmazione (cweb, non più molto usato credo), per i font si è 
inventato il MetaFont e il MetaPost (forse sorpassati dai TrueType, ma 
ancora in uso).
Il TeX utilizza un algoritmo di ottimizzazione globale per spezzare un 
paragrafo in righe. Questo (che io sappia) non lo fa nessun'altro word 
processor e, in effetti, il TeX è l'unico che riesca a gestire la 
sillabazione delle parola nella composizione delle righe.
Le computazioni per l'impaginazione vengono fatte tutte in virgola fissa 
(se ci pensate è la cosa giusta da fare)... e la genialità di Knuth si 
capisce da come ha scelto l'unità minima di misura per la posizione 
degli oggetti nella pagina. Voi che avreste scelto?
E.

 programmazione (cweb, non più molto usato credo)
In realtà web (ora si chiama cweb, da quando genera codice c, prima
faceva pascal) è più di un linguaggio di programmazione: è un tool per
literate programming.


 rinunciato.
Mah, non so, ho la sensazione che pensi che io in fondo 
disprezzi i consigli, mentre li leggo con interesse e mi sforzo 
di capirne le ragioni. Mi sono anche accorto (me lo hanno fatto 
notare in realtà) che non mi spiego molto bene.
Cmq, avere chiesto suggerimenti qui sul NG mi è servito, mi sono 
arrivati spunti utili. Mi spiace se ho dato la sensazione che 
gli aiuti non siano stati graditi, lo sono stati.
Ciò detto doverosamente, poi un po' le cose si imparano anche 
sbattendo la faccia, no ?
ciao
Soviet_Mario

 sbattendo la faccia, no ?
Alcune si, altre si sbatte la faccia e non si sa perchè.


 farebbe danni.
Io sto parlando di *metaprogrammazione* tramite i template, ovvero di 
generazione di codice.
Kiuhnm