Newsgroup: it.comp.lang.c++
Titolo: x Maurus: string to int e viceversa

Ciao,
intanto grazie per i consigli sui due thread dei giorni scorsi.
In effetti ho risolto il problema sia utilizzando il c_str() di string, sia
grazie al template che mi hai suggerito:
template <class Num>
  std::string to_string( Num n )
  {
    std::ostringstream oss;
    oss << n;
    return oss.str();
  }
Ora, mi chiedevo, e fare un template che mi faccia "from_string"? cioè da
stringa a variabile numerica?
Ho abbozzato qualcosa con istringstream, ma non riesco a farlo andare...
Hai un'idea al volo?
Grazie.


Ciao,
intanto voglio dire che quel template non era farina del mio sacco ma fu
postato tempo fa nel ng come correzione a una versione che diedi  che non
era sufficentemente aggiornata col C++.
In secondo luogo, fare una funzione template che faccia l'inverso e' piu'
complicato in quanto da una stringa bisogna sapere che tipo e quanti numeri
vuoi estrapolare.
<tipo_ritorno> from_string(std::string str)
Ad esempio se avessi due stringhe di questo genere:
"1 2.3"
"2.3 1"
Cosa vorresti che ti tornasse la funzione e in che tipo?
E un'ultima cosa:
e' meglio non postare messaggi personalizzati nel ng.
Tutti possono rispondere e molti lo fanno meglio di me.
Maurus

 Cosa vorresti che ti tornasse la funzione e in che tipo?
Ti semplifico le cose in questo modo, dimmi se ti va bene:
#include <iostream>
#include <sstream>
template <class Num>
std::string to_string( Num n )
{
   std::ostringstream oss;
   oss << n;
   return oss.str();
}
template <class Num>
void from_string( Num &num, std::string str )
{
   std::stringstream stream;
   stream << str;
   stream >> num;
}
int main()
{
   int i = 10;
   double d = 2.345;
   std::string strInt = to_string(i);
   std::string strDouble = to_string(d);
   std::cout << "strInt = " << strInt << " strDouble = " << strDouble <<
std::endl;
   int numInt;
   double numDouble;
   from_string(numInt, strInt);
   from_string(numDouble, strDouble);
   std::cout << "numInt = " << numInt << " numDouble = " << numDouble <<
std::endl;
   system("PAUSE");
   return 0;
}
Ciao
Maurus

...
A occhio dovrebbe essere proprio quello che mi serviva. Avevo avuto la
stessa idea ma mi sfuggiva
come usare lo stream per il passaggio.
Grazie mille.
Ciao

 }
perche` usare un reference per restituire il valore? IMHO e` meglio:
template<class T>
T from_string(std::string s)
{
  std::istringstream ist(s);
  T result;
  ist >> result;
  return result;
}
int n = from_string<int>("34");
in ogni caso e` questione di gusti: l'unica restrizione e` che la mia 
versione richiede che T abbia un costruttore di default, pero` IMHO e` 
piu` comoda da usare.
Nota infine che questa funzione non e` limitata ai numeri: puo` 
funzionare con qualsiasi tipo che puo` essere estratto da uno stream, 
quindi anche quelli definiti dall'utente.
ciao Anto
-- 
"Computer science is not about computers any more than astronomy
is about telescopes." -- EW Dijkstra

 ciao Anto
Giusta correzione dell'esperto Antonio!
Sai la mia e' un'abitudine a lasciare il ritorno di funzioni per eventuali
codici di errore da far testare al chiamante, per cui sono sempre portato a
passare per riferimento parametri piu' che tornare il valore.
Sono d'accordo che ma tua soluzione sia migliore in quanto piu' generale.
Ora visto che ho un vuoto di memoria rinfrescami un po' le idee, nel tuo
caso di funzione template che ritorna un valore di tipo parametrico T, e'
necessario specificare il tipo <int> (nel tuo esempio) ?
Che problemi ci sarebbero nel fare questo?:
int n = from_string("34");
Non esiste deduzione implicita del parametro, con il fatto che il valore di
ritorno sia assegnato ad un int?
Maurus

 Maurus
Saluti
R.I.


Perfetto, questo del parametro template di default risolve in parte il mio
dubbio che pero' rimane:
perche' esiste la deduzione implicita dei parametri, ma questa deduzione non
e' applicabile al tipo di ritorno?
Forse mi manca qualche concetto fondamentale.
Grazie Rosario per avermi schiarito le idee.
Maurus

 valore di ritorno sia assegnato ad un int?
no. Se ci pensi e` una situazione analoga a questa:
int foo() { ... }
double foo() { ... }
int x = foo();
come ben sappiamo il codice sopra e` errato: infatti in C++ non esiste 
overloading sul tipo di ritorno e quindi il compilatore non sarebbe in 
grado di determinare quale funzione chiamare.
Il nostro template funziona allo stesso modo: uno potrebbe richiamare la 
funzione *senza* memorizzare il risultato:
double x = from_string("34");
int y = from_string("34");
from_string("34");
quale funzione dovrebbe chiamare il compilatore nell'ultima riga?


   T from_string(std::string s) {
[cut]
purtroppo non e` possibile: e` possibile specificare il parametro di 
defualt soltanto delle classi-template ma non delle funzioni-template.
In alternativa e` possibile fornire un overloading della funzione 
template:
template<class T> T from_string(std::string s)
{
... 
}
int from_string(std::string s)
{
     retrun from_string<int>(s);
