template-Spezialisierung mit zusätzlichem template-Argument versehen&&template-Funktion aus Spezialisierung ders



  • Die partielle Template- Spezialisierung funktioniert nur bei Klassen.
    Ich hoffe, das hier hilft dir weiter:

    template<class T,class U>
    class A {
    public:A() {std::cout<< "allgemeines A \n";}};
    
    template<class U>
    class A<bool,U> {
    public:A() {std::cout<< "spezielles bool A \n";}};
    
    template<class T>
    class A<T,int> {
    public:A() {
    std::cout<< "spezielles int A \n";}};
    
    intmain() {
    A<bool,float> a1;
    A<float,int> a2;
    A<int,float> a3;
    return0;
    


  • @Spawn
    Wer hat denn hier was von partieller Spezialisierung erzählt?
    Natürlich kann man Template Funktionen auf namespace Basis spezialisieren.
    Wie wärs mit expliziter Spezialisierung? Allerdings wird das was Mis2com vorhat damit nicht funktionieren, weil der Compiler allein vom Rückgabewert das Template Argument nicht herleiten kann. Aus den Parametern allerdings sehr wohl:

    template<class T>
    T machwas(T x)
    {
    }
    
    // spezialisiert für int
    template<>
    int machwas(int x)
    {
    }
    


  • Gut, machen wir es so.
    Wobei der Rückgabewert natürlich auch void sein kann.

    #include <iostream>
    #include <conio.h>
    
    using namespace std;
    
    template<class T>
    T machwas(T t){
        cout << "normales machwas" << endl;
    }
    
    template<>
    int machwas<int>(int i){
        cout << "machwas mit int" << endl;
    }
    
    template<>
    char machwas<char>(char c){
        cout << "machwas mit char" << endl;
    }
    
    int main(){
        machwas(5.5);
        machwas<int>(2);
        machwas<char>('c');
        system("Pause");
        return 0;
    }
    


  • Spawn schrieb:

    Gut, machen wir es so.
    Wobei der Rückgabewert natürlich auch void sein kann.

    #include <iostream>
    #include <conio.h>
    
    using namespace std;
    
    template<class T>
    T machwas(T t){
        cout << "normales machwas" << endl;
    }
    
    template<>
    int machwas<int>(int i){
        cout << "machwas mit int" << endl;
    }
    
    template<>
    char machwas<char>(char c){
        cout << "machwas mit char" << endl;
    }
    

    glaube ich kaum, dass dein Code sich kompilieren lässt, wo sind denn die Rückgabewerte geblieben? Zudem ist hier das zweite <> redundant, da der Typ aus den Funktionsparemetern hergeleitet wird.



  • Wobei ich hier aber auch kein Template-Argument in den Spezialisierungen habe, und das ist das Problem, weil sich nämlich aus dem Typ der Spezialisierung ein neuer Template-Parameter ergibt.
    Allerdings scheint mir obige Lösung die Richtige zu sein; leider klappt das nicht bei mir, weil ich noch mit VC6.0 rumheule.

    MfG Eisflamme



  • Der Code lässt sich unter dev- c++ sehr gut compilieren und ausführen, wenn man mal die Warnungen ignoriert.
    Aber das sollte doch wirklich nicht das Problem sein, oder?
    Also noch mal mit Rückgabe Wert:

    #include <iostream>
    #include <conio.h>
    
    using namespace std;
    
    template<class T>
    T machwas(T t){
        cout << "normales machwas" << endl;
        return t;
    }
    
    template<>
    int machwas<int>(int i){
        cout << "machwas mit int" << endl;
        return i;
    }
    
    template<>
    char machwas<char>(char c){
        cout << "machwas mit char" << endl;
        return c;
    }
    
    int main(){
        machwas(5.5);
        machwas<int>(2);
        machwas<char>('c');
        system("Pause");
        return 0;
    }
    

    VC 6 bekommt Probleme mit templates, wenn du weiter mit Spezialisierungen arbeiten willst, solltest du den GNU- Compiler benutzen, der kann das.



  • Wo habe ich da in den Spezialisierungen neue Template-Argumente?
    Mir geht es konkret hier drum:

    template<class T>
    void bla(T a)
    {
    ...
    }
    
    template<class T>
    void bla(complex<T> a)
    {
    ...
    }
    

    Jetzt soll dies Beides möglich sein:

    bla(10.);
    bla(complex<10>);
    bla(complex<10.>);
    bla(complex<10.f>);
    

    usw.

    MfG MAV



  • Also wenn deine spezialisierte Methode eigentlich immer aufgerufen werden soll und die normale Methode nur in bestimmten Fällen, ist das genau das Gegenteil von dem, warum man templates spezialisiert. Du spezialisierst doch, um nur in bestimmten Fällen eine andere Methode aufzurufen als die normale.
    Das geht mir dazu gerade durch den Kopf.
    Und dann brauchst du für jede Spezialisierung eine eigene, spezialisierte Methode.

    Mehr fällt mir dazu jetzt nicht ein.
    Sorry.



  • Ich hab's mal ausprobiert... g++ übersetzt

    #include <iostream>
    #include <complex>
    using namespace std;
    
    template<class T>
    void bla(const T& a)
    {
    	cout << "normales bla\n";
    }
    
    template<class T>
    void bla(const complex<T>& a)
    {
    	cout << "bla complex\n";
    }
    
    int main(int argc, char* argv[])
    {
    	bla(10.);
    	bla(complex<int>(10));
    	bla(complex<double>(10));
    	bla(complex<float>(10.f));
    	return 0;
    }
    

    ohne Probleme und liefert auch das gewünschte Ergebnis. VC6 konnte ich nach einigem Ausprobieren schließlich mit

    #include <iostream>
    #include <complex>
    using namespace std;
    
    template<class T>
    void bla_impl(const T& a)
    {
    	cout << "normales bla\n";
    }
    
    template<class T>
    void bla_impl(const complex<T>& a)
    {
    	cout << "bla complex\n";
    }
    
    template<class T> inline
    void bla(const T& a)
    {
    	(*(static_cast<void (*)(const T&)>(&bla_impl)))(a);
    }
    
    int main(int argc, char* argv[])
    {
    	bla(10.);
    	bla(complex<int>(10));
    	bla(complex<double>(10));
    	bla(complex<float>(10.f));
    	return 0;
    }
    

    zur Mitarbeit überreden 😃



  • Mis2com schrieb:

    weil ich noch mit VC6.0 rumheule

    Wieso holst du dir dann nicht den MSC 7.1 von der MS Homepage. Den gibst dort wohl in der Optimizing Version kostenlos. Imo sollte man den VC 6 nicht mehr benutzen, weil er einfach zu alt ist.


Anmelden zum Antworten