Newsgroup: it.comp.lang.c++
Titolo: numeric_limits

Salve a tutti,
è possibile che l'itruzione
if (numeric_limits<T>::is_specialized) x=0;
non si possa eseguire se T è una classe che non ha un costruttore che 
accetta un int in ingresso?
Cioè non riesco a compilare perchè il compilatore di dice che non trova 
tale costruttore. Posso anche mettercelo un costruttore che accetta un 
int, ma preferirei di no.
Ringrazio in anticipo,
ciao
marco

Marco Dalai wrote:

sinceramente mi sembra strano, il costruttore non dovrebbe nemmeno 
essere richiamato visto che stai accedendo a membri statici di una 
classe. Ma per curiosità, hai provato a definire un costruttore che 
accetta un int? che ti dice?
-- 
"In culo a Osama Bin Laden, ad Al Qaeda e a quei cavernicoli retrogradi 
dei fondamentalisti di tutto il mondo! In nome delle migliaia di 
innocenti assassinati vi auguro di passare il resto dell'eternità con le 
vostre 72 puttane ad arrostire a fuoco lento all'inferno! Stronzi 
cammellieri con l'asciugamano in testa, baciate le mie nobili palle 
irlandesi!"

 accetta un int? che ti dice?
Ciao, grazie mille per la risposta ultrarapida.
Se metto il costruttore, ad esempio Pippo::Pippo(int=0), funziona.
Non riesco a capire, ma onestamente io ne so molto poco, sto muovendo i 
primi passi.
se servono altri dettagli li posto volentieri.
Posso aggiundere che ho un
template vettore<T>
all'interno del quale, se T è numerico, inizializzo a zero gli elementi.
Poi però voglio farmi un vettore di mie oggetti Pippo (e non devo 
inizializzarle, ci pensa il costruttore, che però non accetta parametri 
interi) e devo anche però dire che la mia classe Pippo è ereditata da 
vettore<int>.
Ma questo non dovrebbe creare problemi.
Spero di non aver fatto errori stupidi.
Ciao
marco

 template vettore<T>
template<class T>
class vettore
{
..
}
(vettore è una classe)
ciao
marco

 marco
sinceramente, io non saprei cosa dirti. Magari se provassi a postare un 
pezzo di codice compilabile che riproduce il problema...


 pezzo di codice compilabile che riproduce il problema...
Grazie!! Non ci crederai ma ho capito il problema cercando di riprodurre 
l'errore in un codice all'osso.
In effetti è possibile fare quella cosa.. l'errore è in un altro punto. 
Già che ci sono lo espongo: in realtà l'istruzione era
if (numeric_limits<T>::is_specialized) x= (T) 0;
avevo cioè messo un cast sullo zero. E lì mi dà errore se T non è numerico.
Onestamente non capisco lo stesso perchè questo succeda, l'istruzione 
non dovrebbe essere saltata se T non è numerico? Qui mi sta che sto 
fondendo con le storie di precompilatore ec..
Se posso aggiungere quindi una domanda, se tolgo il cast, sono sicuro 
che l'inizializzazione venga fatta in modo corretto anche se T è float?
Ricordo di aver avuto problemi in passato passando costanti intere dove 
ci si aspettava un float.
Cmq grazie mille, mi hai davvero risolto il problema!
Ciao
marco

 fondendo con le storie di precompilatore ec..
infatti, è una if non una #ifdef
Il compilatore VEDE cmq quel codice, e non potendo sapare se T è 
numerico o meno a compile time, deve predisporre la chiamata (il 
cast) afffinché sia pronta per il run time. E il cast dello zero 
ad un tipo complesso (senza costruttore numerico monoargomento) 
non riesce a farla. Coi puntatori si cmq .... potresti provare a 
usare puntatori nel cast ?
Qui probably mi sbilancio e sparo uan cavolata, ma penso (stante 
anche al testo dell'errore originale), che non trovando una 
conversione standard da ZERO numerico a T-zero, tenti di 
interpretare il cast come T(0). In ogni caso prova l'idea del 
puntatore a T.
Ciao
Soviet-Mario


 cast) afffinché sia pronta per il run time. [...]
Penso che la soluzione migliore sarebbe usare un po' di template-magic.
Se l'idea originale e' qualcosa di simile:
------------------------------------------------------------------------
template <typename T>
void foo(T& x)
  {
  if (std::numeric_limits<T>::is_specialized) 
    x= (T) 0;  /* (*) */
  }
------------------------------------------------------------------------
Perche' la riga (*) non venga presa in considerazione se T non e' un numero,
si puo' usare una classe template con qualche spiecializzazione esplicita.
Il codice diventa qualcosa di simile:
------------------------------------------------------------------------
template < typename T, bool isNumeric >
struct NumericHelper
  {
  static void clear( T& ) {}  /* non fa niente (non e' un numero) */
  };
template < typename T >
struct NumericHelper<T,true>
  {
  static void clear( T& v ) { v = T(0); } /* setta pari a "zero" */
  };
template <typename T>
void foo(T& x)
  {
  NumericHelper< T, std::numeric_limits<T>::is_specialized >::clear(x);
  }
------------------------------------------------------------------------
Che ve ne pare?
Ciao!
-- 
Qual'e' il colmo per uno studente-lavoratore?
Avere un quadrato che si crede un rettangolo.

 ci si aspettava un float.
suppongo che dipenda da cos'è x..


 si aspettava un float.
Si ne sei sicuro. Ad ogni modo valuta uno schema del genere:
using namespace std;
class Pippo { //classe qualsiasi
public:
 Pippo() { xp = 0;}
 ~Pippo() {}
private:
 int xp;
};
template <class T>
class TemplateX {
public:
 TemplateX() {} //costruttore
 template <class T>
 T InitX () {    //template function di inizializzazione
  //inizializza T generico
  x = 0;
  return x;
 }
 template <>
 Pippo InitX() { //template function di inizializzazione specializzata per 
la classe Pippo
  Pippo temp;
  x = temp;
  return x;
 }
 //queste due specializzazioni sotto (int e float) in realtà se lasci x = 0 
le puoi anche omettere
 //perche vale quella per T generico
 template <>
 int InitX () { //template function di inizializzazione specializzata per 
int
  x = 0;
  return x;
 }
 template <>
 float InitX () { //template function di inizializzazione specializzata per 
float
  x = 0;
  return x;
 }
//...
 ~TemplateX() {}
private:
 T x;
};
int main()
{
 TemplateX<Pippo> tx;
 Pippo p;
 p = t.InitX<Pippo>();
return 0;
}
In questo modo hai sfruttato meglio le possibilità dei template ossia il 
check dei tipi a compile-time.
Ciao
Andrea

 fondendo con le storie di precompilatore ec..
Fammi capire: tu vuoi fare una cosa come la seguente?
if (numeric_limits<T>::is_specialized)
  x = (T) 0;
else
  x = T();
Se e' cosi' la cosa piu' semplice e' contare sul fatto che per i tipi
numerici scrivere T() equivale a inizializzare a zero, quindi ti basta
scrivere
x = T();
Senza ricorrere a template, ecc.
Ciao,
Nicola

 Se posso aggiungere quindi una domanda
...
Wow! Caspita, ringrazio tutti moltissimo! Non seguivo questo gruppo ma 
mi sa che inizierò, mi pare molto attivo. Grazie davvero a tutti, ho 
avuto parecchi punti di vista.
ciao
marco