Newsgroup: it.comp.lang.c++
Titolo: Argomenti di default nei template

Guardate il seguente codice:
template<class T=int> T zero()
{
  return T();
}
int main()
{
  return zero();
}
Il g++ 3 mi da' questo errore:
prova.cc:2: default argument for template parameter in function 
template `T zero()'
prova.cc: In function `int main()':
prova.cc:8: no matching function for call to `zero()' 
C'e' qualcosa che non va? E' un bug del g++?
ciao Anto
-- 
Antonio Cuni, 19 anni, studente
Brainbench C++ Master: 4.6, higher than 98% of all previous test takers.
C Language: 3.32, higher than 79% of all previous test takers.
Guida C/C++ di Programmazione.it: 
http://cpp.programmazione.it

 C'e' qualcosa che non va? E' un bug del g++?
L'unica cosa che forse non va e' che il messaggio d'errore "default argument for
template parameter in function template `T zero()'", pur essendo assolutamente
corretto, poteva essere piu' chiaro.
Il problema e' che non puoi specificare un valore di default in una function
template (o member template) ma solo in una class template.
Standard, capitolo 14, paragrafo 1, capoverso 9.
--
Andrea Ferro
---------
Brainbench C++ Master. Scored higher than 97% of previous takers
Scores: Overall 4.46, Conceptual 5.0, Problem-Solving 5.0
More info 
http://www.brainbench.com/transcript.jsp?pid=2522556

 
GCC ha ragione. Una funzione template non può avere argomenti di default
per i parametri (cf. std 14.1/9).
Max

 C'e' qualcosa che non va? E' un bug del g++?
Direi di no. Tratto dal draft pre votazione:
14.1.
-9- A default template-argument is a template-argument (temp.arg)
specified after = in a template-parameter. A default template-argument
may be specified for any kind of template-parameter (type, non-type,
template). A default template-argument may be specified in a class
template declaration or a class template definition.
A default template-argument shall not be specified in a function
template declaration or a function template definition, nor in the
template-parameter-list of the definition of a member of a class
template.
E` un po' piu` brutto, comunque, se ti serve puoi fare cosi`:
template <class T=int> struct ze
{
    static T ro() { return T();}
};
int main()
{
    return ze<>::ro();
}
ciao
Massimo

template (o member template) ma solo in una class template.
E perché? Non č un'inutile asimmetria? O c'č qualche motivo che mi
sfugge?
-- 
Marco Barisione (ICQ 84277092)
Su it.news.gruppi si sta discutendo della creazione di it.comp.lang
dove si parlerą dei linguaggi senza un proprio newsgroup e dei
confronti fra i diversi linguaggi.
Se sei interessato unisciti alla discussione.

 sfugge?
Penso che sia dovuto al fatto che la risoluzione degli overload e' gia'
complicata cosi' com'e', senza dover tener conto anche di eventuali
argomenti di default.
Ciao,
Nicola

 argomenti di default.
beh, non credo che il parametro di default la complichi piu' di tanto. Per 
risolvere il problema, ho fatto cosi' (vabbe', la funzione reale ha un 
altro nome ;-)
template<class T> T zero() { return T(); }
int zero() { return zero<int>(); }
L'effetto e' esattamente lo stesso che avere il parametro T di default. 
Sinceramente, continuo a non capire il perche' non sia possibile fare un 
cosa del genere, ma ne prendo atto...


 cosa del genere, ma ne prendo atto...
Ti sei risposto da solo. Perchč puoi ottenere lo stesso effetto anche senza
sfruttando l'overload.
Nota che la stessa cosa vale per la partial template specialization (che piů
correttamente si chiama, appunto, "Class template partial specialization").



non sareppe piu' corretto scrivere:
    template<>int zero (){ return zero<int>(); }
cioe' definire la funzione zero come specializzazione del template zero<>
invece che come funzione a parte?
quale dei 2 approcci e' preferibile (e quale consigliato dallo standard)?
bye
Touch

 invece che come funzione a parte?
Nel caso specifico e' un errore, perche' la specializzazione sarebbe
definita in termini di se stessa. In generale non si ottiene la stessa
cosa, perche' in assenza di parametri della funzione da cui dedurre
quelli del template, la specializzazione andrebbe chiamata come:
int i = zero<int>();
e non come 
int j = zero();
Ciao,
Nicola

 invece che come funzione a parte?
le funzioni non si possono parzialmente speciallizare.
Ciao
Gaetano.
-- 
Posted from 
dell-01.mm.eutelsat.org
 [194.214.173.17] 
via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 le funzioni non si possono parzialmente speciallizare.
Vero, anche se quella di Simone non e' una specializzazione parziale.
Ciao,
Nicola

 wrote in message
news:3BC5B208...@divalsim.it...

a parte che ho scritto sbagliato (mi hai fatto notare che avevo definito la
funzione in termini di se' stessa... ovviamente il corpo era return T();
ho capito anche la seconda precisazione: uno avrebbe dovuto scrivere
zero<int>() tutte le volte infatti
pero': veramente le funzioni non si possono specializzare parzialmente?
cioe' questo e' scorretto?
template<class T1, class T2>
    void f (T1 x, T2 y)
    {
        ... // fa qualcosa con x e y...
    }
template<class T1>
    void f (T1 x, int y)
    {
        ... // fa qualcosa con x e y...
    }
questo e' scorretto? mentre (immagina un codice analogo) per le classi e'
corretto?
grazie
Simone

 Vero, anche se quella di Simone non e' una specializzazione parziale.
Avevo letto male


 corretto?
La specializzazione parziale delle funzioni template e' effettivamente
vietata. La motivazione e' che gia' la risoluzione degli overload e' una
delle parti piu' complesse del linguaggio; aggiungere a questo la
combinazione tra specializzazione parziale e deduzione degli argomenti
sarebbe stato troppo. 
Nota pero' che il caso del tuo esempio *non* e' tecnicamente una
specializzazione parziale,  bensi un overload tra funzioni template e
questo e' perfettamente legale, posto che le combinazioni di parametri
di template e di funzione differiscano tra i diversi overload. Quello
che non puoi proprio fare e' ad esempio:
template <typename T> T f() { return T(); }
template <typename T> T * f<T *>() { return 0; }
Ciao,
Nicola

     }
questo e' un overload.
Una partial specialization e' la seguente:
template<class T1, class T2>
    void f (T1 x, T2 y)
    {
    }
template<class T1, int>
    void f<T1, int> (T1 x, int y)
    {


     }
Ciao,
Nicola

 template <class T1>
ho cancellato troppo poco.


 specialization").
non ho ben capito: mi puoi fare un esempio?


 non ho ben capito: mi puoi fare un esempio?
Un esempio di cosa?
Ci sono dei post in questi giorni dove si parla di specializzazione
parziale (esempio compreso anche se in prima battuta errato), forse ti
basta quello.
O non hai capito cosa volevo dire.
Volevo dire che la partial template specialization (cosi' come i
template parameter dafault) non si applica(no) alle templated function
ma solo alle templated class.


 ma solo alle templated class.
ok, grazie. In effetti il discorso era abbastanza chiaro, ma si vede che 
dormivo...
