Newsgroup: it.comp.lang.c++
Titolo: Funzioni: come ritornare più di un valore ?

Ciao,
è possibile far ritornare alle funzioni più di un valore ?
Giuseppe

 Giuseppe
Si e no!
Propriamente no!
In pratica puoi ritornare un array, una struttura, una classe, una lista, un
vector etc....
Quindi si riesce sempre a ritornare piu' di un valore (anche se non
propriamente!).
Inoltre ricordati che e' anche possibile anche fare una cosa del genere:
void Ritorna2Valori(int a, int b, int &sum, int &mul){
     sum=a+b;
     mul=a*b;
}
La chiamata sarebbe:
Ritorna2Valori(4,6,somma,moltiplicazione);
Questo esempio e' orribile e poco elegante, ma serve solo a farti vedere che
in questo caso la mia funzione e' void eppure passando 4 e 6, alla fine
della chiamata ho i due valori che volevo (somma e moltiplicazione ) nelle
rispettive variabili.
Ti prego di scusare il mio esempio orribile!
Tommy

 
No. Perň č possibile restituire una struct o usare argomenti di tipo
reference non const per restituire valori.
La libreria di Boost offre un comodo meccanismo template per definire
"tuple" a N valori. Ad es:
 boost::tuple<int,int>       func1();
 boost::tuple<int,int,char>  func2();
 
http://www.boost.org/libs/tuple/doc/tuple_users_guide.html
 
Max
 

 Tommy
E' un trucco di programmazione veramente valido, altro che orribile !
Grazie.
Giuseppe

 E' un trucco di programmazione veramente valido, altro che orribile !
No, confermo che è orribile. :-)
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

 
E' una questione di opinione ? Se no, puoi spiegare le ragioni
per cui affermi questo ?
Ciao
Giuseppe

 per cui affermi questo ?
Dai, su e' cosi' e basta!
La funzione e' orribile. Ogni funzione dovrebbe svoglere una sola funzione.
La mia ne svolge due e non e' nemmeno tanto chiaro quali.
Tra le altre cose 2 variabili (somma e moltip) vengono modificate e questo
potrebbe non essere tanto chiaro
e riservare sorprese a chi la usa.
Il nome della funzione non aiuta a capire cosa facesse.
In generale ogni funzione deve svolgere una sola funzione (piu' o meno).
Nel mio caso si sarebbero dovute usare 2 funzioni.
Molto spesso quando si vuole ritornare piu' di un valore si e' pensata male
la funzione, specialmente se i valori non hanno nulla in comune (come add e
molt. Caso diverso invece array e strutture, questi hanno qualche cosa in
comune....)
In sostanza sono accettabili funzioni che ritornano array, strutture,
classi, vector, liste etc..... tutte queste possono essere ridotte in testa
ad "una" unita': "UNA lista di prodotti", "UNA struttura contenente tutti i
campi relativi a persona", etc...
Quando non riesci a mettere UN, UNA (come in queste frasi) c'e' caso che la
funzione sia mal progettata!
Questo e molto altro ancora rendono il mio esempio orribile. L'ho fatto in
un momento di fretta e pigrizia mentale per ricordarti dei reference che se
pur in casi molto rari a volte possono essere usati!
Tommy

 pur in casi molto rari a volte possono essere usati!
Prima di tutto calmati :-)
Il tuo esempio e' perfettamente corretto riguardo alla sintassi,
ed era su questa che ci si interrogava.
E anche sensato (in un certo senso).
Il prodotto e la somma di due numeri non sono funzioni scorrelate,
visto che hanno gli stessi operandi. (E se proprio uno vuole, puo'
pensare che in questo modo il compilatore non deve caricare gli
operandi due volte, come potrebbe accadere spezzando "la cosa" in due
funzioni,etc.etc.).
Il concetto di una funzione che deve ritornare solo un valore
mi sembra un po' limitativo e sfumato. Anche perche' tu stesso affermi
che una struttura in cui i campi hanno qualcosa a che fare gli uni
con gli altri sono una UNA cosa sola e quindi legittimi.
Posso farti tanti esempi di funzioni che in modo naturale devono
ritornare piu' valori perche' li calcolano simultaneamente.
Che poi uno voglia inscatolarli o meno in
una struct direi che sono affari suoi (e dipende dal contesto).
Se la mia funzione ritorna in modo naturale due interi che vengono
calcolati simultaneamente non vedo perche' non posso scrivere
void fun(int *x, int *y) (o con &, come ti pare). E' molto
piu' semplice e chiaro che creare una struttura ad hoc per contenerle
e poi non utilizzarla altro che per il passaggio a questa funzione.
Per esempio considera una funzione per la fattorizzazione LUP di una 
matrice. (per la soluzione di piu' sistemi lineari con la stessa matrice 
o per altri calcoli).
Come minimo mi deve restituire i fattori triangolari L U e
la matrice di permutazione P rappresentata come un vettore e poi mi
deve fornire un valore (per esempio il minimo pivot utilizzato) che mi
da una idea di eventuali problemi di instabilita' numerica etc.etc.
Quindi in questo caso devo restituire due matrici di double un array di
int e un double. Non posso certamente fare 4 funzioni separate, visto
che i valori che calcolo sono ottenuti simultaneamente durante un
calcolo. Ma anche l'idea di ficcarli tutti in una struct non e' detto
che sia vincente, visto che poi magari li utilizzero' separatamente
etc.etc. e sono contrario alla proliferazione incontrollata di
struct e classi.
(non sto dicendo che non si possa risolvere il problema sopra
in altro modo, e' solo un esempio).
Insomma, come si e' gia' capito, sono allergico alle affermazioni
"da manuale" del tipo "Questo e' sempre sbagliato". Preferisco
pensare di volta in volta alla soluzione piu' idonea, senza preconcetti.
ciao,
g.

 Se no, puoi spiegare le ragioni per cui affermi questo ?
Il passaggio per indirizzo va contro l'information hiding. Se non è
proprio necessario (come, per motivi di efficienza, nel caso di grosse
strutture dati) è meglio utilizzare quello per valore. Il succo del
discorso è che la visibilità di una variabile non dovrebbe mai
estendersi al di fuori del blocco nel quale è definita e tale visibilità
dovrebbe, inoltre, essere limitata al blocco più interno possibile.
