Πόσο καλά τα πάει ο gcc με τα templates;

Giorgos Keramidas keramida at ceid.upatras.gr
Tue May 2 17:10:11 EEST 2006


On 2006-05-02 13:40, Chameleon <cham_gss at hotmail.com> wrote:
> Έχω gcc 3.4.2
> 
> Ενώ με Visual Studio 2005 ο παρακάτω κώδικας γίνεται κανονικότατα 
> compile και link, με το gcc πήρα το μπούλο.
> (Μέχρι που το δοκίμασα μάλιστα, πίστευα οτι ο κώδικας είναι εντελώς 
> cross-platform γιατί δεν χρησιμοποιεί καμμία βιβλιοθήκη πέρα απο τις 
> standard)
> 
> ------------------
> template<class T>
> static void Wastage1D::clever_erase(vector<T> &v, vector<typename 
> vector<T>::iterator> &its, vector<T> &vo)
> { ........ }
> ------------------
> 
> Έτρεξα τον gcc ως εξής:
> gcc -c wastage1d.cpp
> 
> Το μήνυμα που πετάει ο gcc για τον παραπάνω κώδικα είναι:
> ------------------
> wastage1d.cpp:140: error: cannot declare member function `static void 
> wastage::Wastage1D::clever_erase(std::vector<T, std::allocator<_CharT> 
>  >&, std::vector<typename std::vector<T, std::allocator<_CharT> 
>  >::iterator, std::allocator<typename std::vector<T, 
> std::allocator<_CharT> >::iterator> >&, std::vector<T, 
> std::allocator<_CharT> >&)' to have static linkage
> wastage1d.cpp: In static member function `static void 
> wastage::Wastage1D::clever_erase(std::vector<T, std::allocator<_CharT> 
>  >&, std::vector<typename std::vector<T, std::allocator<_CharT> 
>  >::iterator, std::allocator<typename std::vector<T, 
> std::allocator<_CharT> >::iterator> >&, std::vector<T, 
> std::allocator<_CharT> >&)':
> ------------------

Καλά σου λέει.  Οι static class methods δεν ορίζονται ως `static' στο
σημείο υλοποίησης τους, όταν αυτό είναι εκτός ορισμού του class.  Ετσι
μπορείς να γράψεις:

    #include <iostream>
    #include <iomanip>

    using namespace std;

    template <class T>
    class Foo
    {
    public:
	static void Foomethod() { cout << "Hello world" << endl; };
    };

ή αντίστοιχα:

    #include <iostream>
    #include <iomanip>

    using namespace std;

    template <class T>
    class Foo
    {
    public:
	static void Foomethod();
    };

    template <class T>
    void Foo::Foomethod()
    {
      cout << "Hello world" << endl;
    }

Αυτή είναι μια από τις περιπτώσεις που ο μαλακισμένος τρόπος με τον
οποίο έχει κάνει overload το νόημα της λέξης `static' ο Strousstrup,
όταν σχεδίασε τη C++, είναι λίγο χαζός.

Οταν η λέξη `static' υπάρχει πριν το prototype ή ορισμό μιας method
*ΜΕΣΑ* στον ορισμό της class, τότε το `static' είναι function
visibility/ownership specifier.  Η μη ύπαρξή του σημαίνει object
method, ενώ η ύπαρξή του σημαίνει class method.

Με ένα εντελώς άσχετο και μαστορικά ηλίθιο τρόπο, μόνο και μόνο για
να μπορεί να μας σκοτίζει τα παπάρια ότι η C++ είναι "μια καλύτερη
C", ο ίδιος σχεδιαστής γλώσσας αποφάσισε ότι όταν μια object/class
method ορίζεται *ΕΞΩ* από τον ορισμό του class, σε file scope, τότε
το `static' έχει τη σημασιολογία που έχει το ίδιο keyword σε ANSI C.
Δηλαδή πλέον δεν ορίζει αν το function είναι object ή class method,
αλλά αν το function έχει file scope ή global scope.

Κι έτσι ξέρεις γιατί στο πρώτο παράδειγμα παραπάνω το `static' είναι
όντως σωστό και ορίζει ένα common class method, ενώ στο δεύτερο
παράδειγμα (όπου μπορεί π.χ. ο ορισμός της function/method να είναι
ακόμα και σε άλλο αρχείο) ορίζει κάτι εντελώς διαφορετικό, κι ας έχει
το ίδιο όνομα το `static' keyword και στις δυο περιπτώσεις.

Η C++ φημίζεται για τέτοιες απερίσκεπτες αποφάσεις κατά το design της,
οπότε δεν είναι κάτι ιδιαίτερο περίεργο ότι είναι λίγο χαζός ο τρόπος
που χρησιμοποιεί το `static' keyword.

> Δίνω μια πολύ μικρή πιθανότητα να φταίει το Visual Studio επειδή μου 
> επέτρεψε να γίνει compile κάτι που απαγορεύει η C++, αλλά ο κώδικας 
> είναι πολύ εντάξει ρε γμτ.
> 
> Ουσιαστικά δημιουργώ μια κλάση με άπειρα static members (απο τη στιγμή 
> που είναι template) και το instantiation μπορεί να γίνει οπουδήποτε μέσα 
> στον κώδικα και οποτεδήποτε. Το οτι όμως είναι static member δεν θα 
> έπρεπε να ενοχλεί την κλάση.

Προσοχή στην χρήση του `static'.  Μπορεί να σημαίνει οποιοδήποτε από 4
διαφορετικά πράγματα, ανάλογα με το context.

> Η μόνη σχέση που έχει με την κλάση, ενα public static member είναι
> οτι βρίσκεται κάτω από το όνομά της.

Οχι ακριβώς.  Ξαναδιάβασε τον ορισμό της γλώσσας από τον Strousstrup.
Είναι τερατώδης σε μέγεθος, πολύπλοκος, κλπ κλπ κλπ. αλλά το χειρότερο
που μπορεί να γίνει είναι να γίνεις κι εσύ C programmer :P

> Μεταξύ μας, δεν έχω πάρει ιδέα ποιά είναι η διαφορά μεταξύ gcc, g++
> και c++.  Όλα το ίδιο δεν κάνουν;

Οχι.

Το `gcc' είναι C compiler.

Τα άλλα είναι C++ compilers.

Οι δυο αυτές γλώσσες είναι πολύ διαφορετικές.  Για την ακρίβεια, η μία
από αυτές -- κατά τη γνώμη μου, πάντα -- δεν είναι καν γλώσσα, αλλά
ένα απίστευτο κουβάρι από βλακείες, συγκεντρωμένες γύρω από ένα μικρό
αριθμό πραγματικά χρήσιμων χαρακτηριστικών.




More information about the Linux-greek-users mailing list