Templates kai C++ (SOLVED)

Dimitris Tasoulis dtas at math.upatras.gr
Wed Jul 23 11:50:05 EEST 2003


Eyxaristo paidia gia tis apantiseis  kai to xrono poy afiorosate.
Mou dosate na katalavo poli kala ti akrivos paizei me ta templates
kai pos ginontai ayta compile kai link.


Dimitris Tasoulis



On Wed, 23 Jul 2003, Vasilis Vasaitis wrote:

> On Tue, Jul 22, 2003 at 08:35:25PM +0300, Dimitris Tasoulis wrote:
> > 
> > Geia xara, exo na kano mia periergi erotisi sxetika me tis template 
> > claseis tis C++.
> > 
> > Exo ftia3ei mia template class (List.h) gia double linked list.
> > Prospa8o tora na kano compile to antistixo List.cpp kai ta kataferno mia 
> > xara. Kanontas omos include to List.h sto main kai dinontas 
> > sto g++ to List.o gia na kanei to linking den ta katafernei.
> > 
> > To error pou vgazei einai to e3is:
> > /tmp/ccxRfwoG.o: In function `main':
> > /tmp/ccxRfwoG.o(.text+0x22): undefined reference to `List<int>::add(int)'
> > collect2: ld returned 1 exit status
> > 
> > Mipos mporei na voi8eisei kapoios?
> 
>   Λοιπόν, δικαιολογημένη η απορία σου στη συγκεκριμένη περίπτωση, αλλά
> πρόσεξε τι συμβαίνει:
> 
>   - Όταν μεταγλωττίζεται το List.cpp, ο g++ δε βλέπει την ανάγκη να
> παράγει καμία εκδοχή του template για συγκεκριμένο τύπο, και επομένως
> δεν το κάνει.
> 
>   - Όταν μεταγλωττίζεται το main_bad.cpp, ο g++ δε βλέπει μπροστά του
> κάποιον ορισμό της List<int>::add(int), οπότε αναγκαστικά υποθέτει ότι
> είναι εξωτερικό σύμβολο που θα βρεθεί κατά τη σύνδεση.
> 
>   - Όταν γίνεται η σύνδεση, ο ld δεν έχει ιδέα πού θα μπορούσε να βρει
> τη ζητούμενη συνάρτηση, αφού δεν υπάρχει σε κανένα από τα object files
> που δέχεται ως είσοδο, οπότε εγκαταλείπει την προσπάθεια.
> 
>   Ουσιαστικά, αυτό που θα ήθελες εσύ (υποσυνείδητα τουλάχιστον) είναι
> ο linker, όποτε δε βρίσκει ένα σύμβολο που προέρχεται από κάποιο
> template, να καλεί τον compiler, ο οποίος να παράγει το σχετικό
> template instantiation ανάλογα με την περίπτωση. Δυστυχώς ή ευτυχώς,
> στον κόσμο του Unix, με την όλη φιλοσοφία των ξεχωριστών εργαλείων, δε
> δουλεύουν έτσι τα πράγματα.
> 
>   Από εκεί και πέρα, υπάρχουν δυο τρόποι που μπορείς να λύσεις το
> πρόβλημά σου:
> 
>   - Να συμπεριλαμβάνεις όλους τους ορισμούς και την υλοποίηση του
> template στο αρχείο .h, όπως κάνει όλος ο κόσμος. Το πλεονέκτημα της
> λύσης αυτής είναι ότι ξαφνικά όλα δουλεύουν αυτόματα και χωρίς να
> χρειάζεται να κάνεις τίποτα άλλο. Το μειονέκτημα είναι ότι καταλήγει ο
> compiler να παράγει τα template instantiations για κάθε αρχείο πηγαίου
> κώδικα που χρησιμοποιεί το template (δηλαδή παραπάνω χρόνος
> μεταγλώττισης), και ότι σε «χαζά» περιβάλλοντα ανάπτυξης προγραμμάτων
> (το GNU περιβάλλον *δεν* είναι ένα από αυτά) όλα αυτά τα
> instantiations καταλήγουν σε πολλαπλά αντίτυπα στο τελικό εκτελέσιμο.
> 
>   Αν δε με πιστεύεις ως προς το περί «όλου του κόσμου», απλά ρίξε μια
> ματιά στα αρχεία επικεφαλίδας της βιβλιοθήκης του g++, όπου απλά
> περιλαμβάνονται όλα τα template της πρότυπης βιβλιοθήκης.
> 
>   - Να παράγεις χειροκίνητα όλα τα instantiations που πρόκειται να
> χρησιμοποιήσεις. Π.χ., στη συγκεκριμένη περίπτωση, αρκεί να προσθέσεις
> στο List.cpp ένα:
> 
> 	template List<int>;
> 
>   Τα πλεονεκτήματα και μειονεκτήματα αυτής της λύσης είναι, χωρίς
> καμία έκπληξη, τα ακριβώς αντίστροφα με αυτά της παραπάνω (την οποία
> και προτείνω).
> 
>   Αν έχοντας διαβάσει όλα τα παραπάνω, αυτά δε σου φαίνονται τόσο
> προφανή όσο μου φαίνονται εμένα, ζήτα επιπλέον διευκρινήσεις. ;^)
> 
> 




More information about the Linux-greek-users mailing list