Template mit < oder > o.ä. spezialisieren?



  • Nexus schrieb:

    Da würde C und R nicht als Templateparameter, sondern Parameter der Funktion übergeben, und dann innerhalb des Funktionsrumpfes eine If-Abfrage durchführen.

    Ja bedauerlicherweiße bestimmt das R und C ja den template-Klassentyp "type". Aber nichtsdestotrotz könnte ich natürlich in der Funktion vergleichen.... Jedoch fände ich eine spezialisierung hübscher und übersichtlicher ^^ 😮



  • Und da fällt mir auf dass ich eine Kleinigkeit unterschlagen habe ... Meine Funktion nimmt noch ein 2. Argument:

    template< typename T, const unsigned C, const unsigned R >
    void tempFunc( type<T,C,R>, array< XXX >& RESULT ) {} 
    /*
     XXX von RESULT sei R-C wenn R>C und C-R wenn R<C und 13 wenn R==C
    */
    


  • Meines Wissens sind Spezialisierungen nur für bestimmte Argumente der Templateparameter (also z.B. bestimmte Typen) möglich, aber nicht pauschal für irgendwelche Bedingungen, die die Parameter betreffen.



  • template< typename T, const unsigned C, const unsigned R >
    void tempFunc( type<T,C,R>, array< XXX >& RESULT ) {}
    /*
     XXX von RESULT sei R-C wenn R>C und C-R wenn R<C und 13 wenn R==C
    */
    

    wenn es dir nur um den wert zur compile-time geht, kannst du auch folgendes machen

    template< typename T, const unsigned C, const unsigned R >
    void tempFunc( type<T,C,R>, array< XXX >& RESULT )
    {
       const unsigned int result = R > C ? (R - C) : R < C ? (C - R) : 0;
    }
    

    wenn du aber wirklich eine trennung je nach fall haben willst, koennte man sowas auch noch machen

    template<int v>
    struct test
    {
       static void machwas(array< XXX >& RESULT) { ... }
    };
    
    template<>
    struct test<1>
    {
       static void machwas(array< XXX >& RESULT) { ... }
    };
    
    template<>
    struct test<2>
    {
       static void machwas(array< XXX >& RESULT) { ... }
    };
    
    template< typename T, const unsigned C, const unsigned R >
    void tempFunc( type<T,C,R>, array< XXX >& RESULT )
    {
       test<(R > C ? 1 : R < C ? 2 : 0)>::machwas(RESULT);
    }
    

    Meep Meep

    Edit: klammern hinzugefuegt



  • Naja, ob sich das lohnt, nur damit man aus Prinzip keine If-Abfragen hat... Und die ?:-Bedingungsabfrage ist ja auch nicht gerade besser...



  • Nexus schrieb:

    Naja, ob sich das lohnt, nur damit man aus Prinzip keine If-Abfragen hat...

    ob es sich lohnt ist hier aber nicht die frage gewesen.

    Nexus schrieb:

    Und die ?:-Bedingungsabfrage ist ja auch nicht gerade besser...

    was meinst du damit ?
    die brauche ich damit die spezialisierung funktioniert

    Meep Meep



  • Meep Meep schrieb:

    Nexus schrieb:

    Naja, ob sich das lohnt, nur damit man aus Prinzip keine If-Abfragen hat...

    ob es sich lohnt ist hier aber nicht die frage gewesen.

    Trotzdem finde ich den Einwand berechtigt, wenn man aus einfachem Code komplizierten macht, nur um irgendwelche Prinzipien einzuhalten.

    Meep Meep schrieb:

    Nexus schrieb:

    Und die ?:-Bedingungsabfrage ist ja auch nicht gerade besser...

    was meinst du damit ?
    die brauche ich damit die spezialisierung funktioniert

    Ich meine damit, dass man statt des ?:-Operators ebenso eine If-Abfrage innerhalb der Funktion einführen könnte.

    Es ging mir eigentlich um Folgendes:

    Pigeon schrieb:

    Nexus schrieb:

    Da würde C und R nicht als Templateparameter, sondern Parameter der Funktion übergeben, und dann innerhalb des Funktionsrumpfes eine If-Abfrage durchführen.

    Ja bedauerlicherweiße bestimmt das R und C ja den template-Klassentyp "type". Aber nichtsdestotrotz könnte ich natürlich in der Funktion vergleichen.... Jedoch fände ich eine spezialisierung hübscher und übersichtlicher ^^ 😮

    was ich jedoch bezweifle...





  • Nexus schrieb:

    Meep Meep schrieb:

    Nexus schrieb:

    Und die ?:-Bedingungsabfrage ist ja auch nicht gerade besser...

    was meinst du damit ?
    die brauche ich damit die spezialisierung funktioniert

    Ich meine damit, dass man statt des ?:-Operators ebenso eine If-Abfrage innerhalb der Funktion einführen könnte.

    Nein, könnte man nicht, da dann keine Auswertung zur Compilezeit stattfindet. Und das kann durchaus ein Vorteil (bzw. notwendig) sein.

    .filmor schrieb:

    Das hier sollte helfen: http://www.boost.org/doc/libs/1_35_0/libs/utility/enable_if.html

    Inwiefern hilft das? Es geht hier ja nicht um ein An- bzw. Ausschalten einer Funktion sondern um eine partielle Spezialisierung. Und da ist „Meep Meep“s Methode an sich schon die richtige.



  • Nein, könnte man nicht, da dann keine Auswertung zur Compilezeit stattfindet. Und das kann durchaus ein Vorteil (bzw. notwendig) sein.

    ganz unwahrscheinlich ist es nicht, dass der Compiler sowas wegoptimiert:

    if(konstanter_ausdruck)
       //tu dies
    else
       //tu das
    

    Erkennen tun die Compiler das aufjedenfall, wie man an warnungen wie "dieser ausdruck wird immer zu wahr auswerten" etc sehen kann.



  • otze schrieb:

    Nein, könnte man nicht, da dann keine Auswertung zur Compilezeit stattfindet. Und das kann durchaus ein Vorteil (bzw. notwendig) sein.

    ganz unwahrscheinlich ist es nicht, dass der Compiler sowas wegoptimiert:

    if(konstanter_ausdruck)
       //tu dies
    else
       //tu das
    

    Erkennen tun die Compiler das aufjedenfall, wie man an warnungen wie "dieser ausdruck wird immer zu wahr auswerten" etc sehen kann.

    Klar, aber versuch damit z.B. mal die Größe eines festen C-Arrays zu bestimmen oder eben ein Template auszufüllen.



  • Konrad Rudolph schrieb:

    .filmor schrieb:

    Das hier sollte helfen: http://www.boost.org/doc/libs/1_35_0/libs/utility/enable_if.html

    Inwiefern hilft das? Es geht hier ja nicht um ein An- bzw. Ausschalten einer Funktion sondern um eine partielle Spezialisierung. Und da ist „Meep Meep“s Methode an sich schon die richtige.

    Ich glaub', du hast SFINAE nicht verstanden 😉

    template< typename T, unsigned C, unsigned R >
    typename boost::enable_if_c<(R > C), void>::type tempFunc( type<T,C,R>, array<R - C> )
    {
        // R ist größer C
    }
    
    template< typename T, unsigned C, unsigned R >
    typename boost::enable_if_c<(R < C), void>::type tempFunc( type<T,C,R>, array<C - R> )
    {
        // R ist kleiner C
    }
    
    template< typename T, unsigned C, unsigned R >
    typename boost::enable_if_c<R == C, void>::type tempFunc( type<T,C,R>, array<13> )
    {
        // R ist gleich C
    }
    

Anmelden zum Antworten