Tornando alla questione principale, provo a ricapitolare le tre opzioni di scelta in mio possesso:
1)
class A
{
static vector<T> v;
static vector<T*> m[10][10];
...
void fun()
{
for(unsigned int i = 0; i < 10; ++i)
{
for(unsigned int j = 0; j < 10; m[i][j++].resize(0));
}
v.resize(0);
v.reserve(N);
...
riempimento simultaneo di "v" e "m"
...
for(unsigned int i = 0; i < 10; ++i)
{
for(unsigned int j = 0; j < 10; ++j)
{
vector<T*> &r = m[i][j]
for(unsigned int k = 0; k < r.size(); ++k)
{
r[k]-> ...
...
}
}
}
}
};
2)
class A
{
static list<T> v;
static vector<T*> m[10][10];
...
void fun()
{
for(unsigned int i = 0; i < 10; ++i)
{
for(unsigned int j = 0; j < 10; m[i][j++].resize(0));
}
v.resize(0);
...
riempimento simultaneo di "v" e "m"
...
for(unsigned int i = 0; i < 10; ++i)
{
for(unsigned int j = 0; j < 10; ++j)
{
vector<T*> &r = m[i][j]
for(unsigned int k = 0; k < r.size(); ++k)
{
r[k]-> ...
...
}
}
}
}
};
3)
class A
{
static vector<T> v;
static vector<unsigneed int> m[10][10];
...
void fun()
{
for(unsigned int i = 0; i < 10; ++i)
{
for(unsigned int j = 0; j < 10; m[i][j++].resize(0));
}
v.resize(0);
...
riempimento simultaneo di "v" e "m"
...
for(unsigned int i = 0; i < 10; ++i)
{
for(unsigned int j = 0; j < 10; ++j)
{
vector<unsigned int> &r = m[i][j]
for(unsigned int k = 0; k < r.size(); ++k)
{
v[r[k]]. ...
...
}
}
}
}
};
Ragionando meglio, la scelta forse non è più così scontata:
- relativamente al caso 2) con le liste, non mi sembra poi molto efficiente dover deallocare e riallocare la memoria ad ogni chiamata di A::fun();
- il caso 3) con gli indici agli elementi di v va sicuramente bene, ma rispetto al caso 1) richiede un maggior ricorso all'operatore []:
caso 1): r[k]->
caso 3): v[r[k]].
a meno che non si utilizzi un secondo reference:
T &r2 = v[r[k]];
L'utilizzo dei reference, oltre ad una questione di efficienza, è dovuto anche al fatto che nel programma originale, essendo i corrispettivi dei contenitori v e m molto più complessi, senza l'utilizzo dei riferimenti verrebbero righe di codice lunghissime e quindi molto poco leggibili;
- infine per quanto riguarda il caso 1) con i puntatori agli elementi di v, l'unico "contro" è lo spreco di memoria dovuto al ricorso a:
v.reserve(N);
Ho provato allora a valutare il suddetto "spreco": utilizzando sizeof(T) ottengo un valore di 184B, mentre ragionando attentamente su N ho dedotto che la massima dimensione di v dovrebbe essere 135, per un totale quindi di 135*184B=~25KB. Ora è vero che di solito utilizzo molti meno posti dei 135 disponibili, ma così su due piedi 25KB non mi sembrano un problema, o sbaglio?
Già che ci sono poi ne approfitto anche per chiedere un'altra cosa: visto che v è un membro statico della classe A, va bene piazzare il v.reserve(N) in A::fun()? Dal momento che la riallocazione avviene soltanto se N>v.capacity(), sinceramente non ci vedo particolari controindicazioni dal punto di vista pratico, anche se forse dal punto di vista della "buona programmazione" non è il massimo... non so, che dite?