Newsgroup: it.comp.lang.c++
Titolo: Problemi con compilazione di template di classe

Salve a tutti,
mi sto avvicinando allo studio dei template di funzione, ma ho problemi 
anche negli esempi più semplici. Il seguente codice non mi compila:
#include <iostream>
using namespace std;
template <class Tipo>
Tipo min(Tipo a, Tipo b)
{
	return a < b ? a : b;
}
int main () {
int a=10, b=11;
int ris=min(a,b);
cout << "Tra " << a << " e " << b << " il minore e' " << ris << endl;
}
L'errore è:
main.cpp: In function 'int main()':
main.cpp:14: error: call of overloaded 'min(int&, int&)' is ambiguous
main.cpp:6: note: candidates are: Tipo min(Tipo, Tipo) [with Tipo = int]
/usr/lib/gcc/x86_64-linux-gnu/4.0.2/../../../../include/c++/4.0.2/bits/stl_algobase.h:184: 
note:                 const _Tp& std::min(const _Tp&, const _Tp&) [with 
_Tp = int]
Cioè per lui la chiamata a min con 2 interi è ambigua?? Non ho capito 
perchè, non dovrebbe dedurlo dal contesto? E poi il candidato è uno 
solo, ovvero Tipo = int ! Questa cosa mi sta facendo arrabbiare, non 
capisco assolutamente perchè questo comportamento >:(
Tra l'altro lo stesso accade esplicitando il parametro di tipo, ovvero 
sostituendo al codice sopra la riga
int ris=min(a,b); con int ris=min<int>(a,b)
(a parte che non voglio esplicitare il tipo, vorrei che lo deducesse 
automagicamente dal contesto... se no che gusto c'è?)
Uso il g++ versione 4:4.0.2-1 se può essere utile. Grazie a chiunque 
vorrà aiutarmi.
-- 
U4U
Debian GNU/Linux x86_64 edition

 Tipo min(Tipo a, Tipo b)
Tipo min(Tipo &a, Tipo &b)
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
The EMG Music page:         
http://www.emagsoftware.it/emgmusic
 

 Tipo min(Tipo &a, Tipo &b)
Veramente sia sulle dispense che sul libro ( Lippman - Lajoice ) fanno 
gli esempi passando i parametri per valore e non per riferimento. 
Sbagliano prof e questi due guru o il compilatore?


 
dai un'occhiata al file stl_algobase.h alla riga 184.
ciao!

 e questi due guru o il compilatore?
Non c'č dubbio che sbaglio io, figurati. Perņ almeno con quel workaround 
funziona. :-)


 dai un'occhiata al file stl_algobase.h alla riga 184.
LOL! Grazie, ora ho capito :D
Certo che sti progettisti di classi han poca fantasia... hanno chiamato 
la funzione esattamente come la mia!!! :P


 dai un'occhiata al file stl_algobase.h alla riga 184.
Ops! :-) Ecco uno dei problemi ad utilizzare la direttiva
using namespace std;


 
nel file stl_algobase.h c'è il prototipo del template:
template<typename _Tp>
     inline const _Tp&
     mix(const _Tp& __a, const _Tp& __b)
     {
       // concept requirements
       __glibcpp_function_requires(_LessThanComparableConcept<_Tp>)
       //return  __a < __b ? __b : __a;
       if (__a < __b) return __b; return __a;
     }
quindi o usa quella, o cambia nome al suo template.
O sbaglio?
ciao!

 O sbaglio?
Se non avesse utilizzato la direttiva
using namespace std;
il programma avrebbe funzionato regolarmente, ovviamente indicando il 
namespace davanti a
std::cout
std::endl


 std::endl
Eh giŕ, la pigrizia non paga...
Grazie ad entrambi! :)


Scusate se faccio un piccolo cenno, inserendo il using namespace std; e
compilando con devc++ 4.9.9.1 da un errore perchè non compila ?

chiedo scusa per errore non inserendo using namespace std; il
compilatore devc++ 4.9.9.1. non compila e da errore....

 
il copilatore che usa devc++ e' mingw

U4U wrote:
 > mi sto avvicinando allo studio dei template di funzione, ma ho
 > problemi anche negli esempi più semplici. Il seguente codice
 > non mi compila:
 > #include <iostream>
Manca
     #include <ostream>
 > using namespace std;
È qui il probleme. La stessa libertà che fà che il codice si
compila senza #include <ostream> permette che se trovano anche
cose che non vuoi in std::. Come std::min.
 > template <class Tipo>
 > Tipo min(Tipo a, Tipo b)
 > {
 >     return a < b ? a : b;
 > }
 > int main () {
 > int a=10, b=11;
 > int ris=min(a,b);
 > cout << "Tra " << a << " e " << b << " il minore e' " << ris << endl;
 > }
 > L'errore è:
 > main.cpp: In function 'int main()':
 > main.cpp:14: error: call of overloaded 'min(int&, int&)' is ambiguous
 > main.cpp:6: note: candidates are: Tipo min(Tipo, Tipo) [with Tipo = int]
 > 
/usr/lib/gcc/x86_64-linux-gnu/4.0.2/../../../../include/c++/4.0.2/bits/stl_algobase.h:184: 
 > note:                 const _Tp& std::min(const _Tp&, const _Tp&) [with
 > _Tp = int]
 > Cioè per lui la chiamata a min con 2 interi è ambigua??
Il messagio mi sembra chiaro. Ci sono due funzioni template di
min, e tutti due puo essere chiamati con int, senza nessuna
conversione. Allora, e ambigua.
Ce sono due soluzioni possibile:
  -- Lacsi cadere il "using namespace std;", e importare solo i
     nomi di che hai bisogno:
         using std::cout ; using std::endl ;
     o forse meglio, scrivi sempre il nome completo:
         std::cout << ... << std::endl ;
  -- Vieti-ti tutti i nomi nella biblioteca standard. Dunque,
     nessuna funzione che si chiama min da te.
Personalemente, scrivo sempre std::cout, E non definire funzioni
collo stesso nome di funzioni standard. Trovo cosi che è più
leggibile.
 > Non ho capito perchè, non dovrebbe dedurlo dal contesto?
Come?
 > E poi il candidato è uno solo, ovvero Tipo = int !
La norma C++ permette a <iostream> d'includere altri header. Da
essempio, <ostream>, dove si trova l'operator<< che usi con
cout. O <algorithm>, dove si trova una funzione template
std::min, da dove l'ambiguità.
 > Questa cosa mi sta facendo arrabbiare, non capisco
 > assolutamente perchè questo comportamento >:(
Capisco in parte. Ma per diverse ragioni, è stato considerato
troppo difficile a gli implementazioni di vietare l'inclusioni
di altri header, come era stato fatto in C.
E perche tanta rabbia. Il messagio era chiaro di cui viene
l'ambiguità: la funzione std::min..., con _Tp = int. Quando ci
sono templates, è raro d'aver un messagio cosi chiaro; spesso
hai una pagina o due di messagi, senza molta indicazione quello
ti interessa realmente.
 > Tra l'altro lo stesso accade esplicitando il parametro di
 > tipo, ovvero sostituendo al codice sopra la riga
 > int ris=min(a,b); con int ris=min<int>(a,b)
Infatti. Ci sono sempre due funzioni template min.
 > (a parte che non voglio esplicitare il tipo, vorrei che lo
 > deducesse automagicamente dal contesto... se no che gusto
 > c'è?)
 > Uso il g++ versione 4:4.0.2-1 se può essere utile. Grazie a
 > chiunque vorrà aiutarmi.
Depende effetivamente dal compilatore, o piùtosto
dall'implementazione della biblioteca. Ma è autorisato, ed è
probabile che altre implementazioni fanno stesso. O che non lo
fanno oggi, ma lo faranno nella prossima versione.
-- 
James Kanze                                 mailto: 
james...@free.fr
Conseils en informatique orientée objet/
                        Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France 
+33 (0)1 30 23 00 34

 fanno oggi, ma lo faranno nella prossima versione.
Ok, sia d'esempio ai posteri: non usate mai quell'orribile "using 
namespace std;". Prendete pure d'esempio questo messaggio ;)
Grazie anche a te per la risposta, complimenti per l'italiano (con 
qualche ritocchino sarà perfetto, ma se penso al mio francese e che tra 
due settimane vado a Parigi devo solo stare zitto) :P
Merci
-- 
Der Jäger

Der Jäger wrote:
 > James Kanze ha scritto:
 >> Manca
 >>     #include <ostream>
 > A che serve? In tutti i programmi ho visto solo #include
 > <iostream> o al massimo #include <fstream> per lavorare sui
 > file...
Serve a dare le definizioni degli operatori <<. <iostream>
dichiara cin, cout etc., ma non ne dà delle definizioni.
In C++, un header può includere altri -- da essempio, <iostream>
può includere <ostream>. Ma dipende della implementazione.
Nel mio codice, e piutosto raro d'includere <iostream>.
     [...]
 > Ok, sia d'esempio ai posteri: non usate mai quell'orribile
 > "using namespace std;". Prendete pure d'esempio questo
 > messaggio ;) Grazie anche a te per la risposta, complimenti
 > per l'italiano (con qualche ritocchino sarà perfetto, ma se
 > penso al mio francese e che tra due settimane vado a Parigi
 > devo solo stare zitto) :P
Ma ho trovato una seconda cosa interessante: il conflitto a
avuto luogo solo perche <iostream> a includuto <algorithm>. Chi
e permesso, ma non obligato. Essatamente come <ostream> e gli
operatori <<.
