Funktion abhängig von der Datenbreite des Typs?



  • Hi,
    kann man folgendes auch ohne C++0x realisieren?

    template<typename T, size_t N = sizeof(T)>
    void foo(T const &)
    {
      // hier geht es mir nur um die Bytebreite des Typs, sprich N
    }
    


  • Warum nicht

    template <typename T>
    void foo(T const&)
    {
        const size_t N = sizeof(T);
    }
    

    Was willst du genau erreichen?


  • Mod

    Falls du erreichen willst, dass für jedes N eine eigene Funktion erzeugt wird, sollte dies gehen:

    template <typename T, size_t N> void foo_impl(T const&){}
    
    template <typename T> void foo(T const& bar)
    {
        foo_impl<T, sizeof(T)> (bar);
    }
    

    edit: Bzw. das macht keinen Sinn, da das T ja sowieso schon immer unterschiedlich ist und das N keine Rolle mehr spielt. Immerhin kannst du so aber einerseits das N vorgeben, andererseits hast du einen guten Defaultwert.



  • Deine Vorschlag entspricht der aktuellen Umsetzung. Die Idee ist aber die, die Datenbreite direkt als Template-Argument zu übernehmen, so dass der Compiler direkt die richtige Funktion rufen kann. Ich will das mir der Compiler dadurch etwas Arbeit abnimmt und ich nicht selber die Fallunterscheidung machen muss.
    Das führt wahrscheinlich dann gleich zum nächsten Problem, weil es unabhängig vom Typ sein soll. Welches aber nicht erst gelöst werden muss, wenn das erste schon offen bleibt.

    Edit:
    Die Lösung von SeppJ sieht schon mal gut aus. Daran hatte ich aber auch gedacht, das Problem ist nur der Typ. Mich interessiert aber nur die Datenbreite.



  • Nick Unbekannt schrieb:

    Die Lösung von SeppJ sieht schon mal gut aus. Daran hatte ich aber auch gedacht, das Problem ist nur der Typ. Mich interessiert aber nur die Datenbreite.

    Dann lass doch einfach den Typ-Parameter weg... 😕


  • Mod

    Sag lieber direkt worauf du hinaus willst. Dir beim Basteln einer suboptimalen Lösung für ein unbekanntes Problem zu helfen klingt nämlich nicht sehr verlockend.

    Der Wunsch, Templatefunktionen unabhängig von einem der Templateparameter haben zu wollen, klingt jedenfalls schon einmal sehr wild.



  • Wie im ersten Beitrag geschrieben möchte ich, dass mir der Compiler die richtige Funktion auswählt, abhängig von der Datenbreite des übergegebenen Typs. Der Typ selber ist mir dabei egal.

    Btw. Wie kann man mit dem Visual Studio Compiler C++0x Code compilieren?


  • Mod

    Nick Unbekannt schrieb:

    Wie im ersten Beitrag geschrieben möchte ich, dass mir der Compiler die richtige Funktion auswählt, abhängig von der Datenbreite des übergegebenen Typs. Der Typ selber ist mir dabei egal.

    Ja, dann dürfte meine Lösung passend sein. Lass einfach das T bei der foo_impl weg.



  • Nick Unbekannt schrieb:

    Btw. Wie kann man mit dem Visual Studio Compiler C++0x Code compilieren?

    Wenn du Visual Studio 2010 hast und du nur die unterstützen C++0x-Features benutzt: Ohne etwas speziell einzustellen.



  • C++ hat noch etwas altmodische Features wie Ueberladung. Damit ginge das Wahrscheinlich auch.



  • @SeppJ
    Das stimmt das sollte passen. Danke!

    @Nexus
    Ich hab das Beispiel von oben getestet und da kam der erwartete Fehler. Deswegen dachte ich man könnte wie beim GCC noch einem Schalter mitgeben?
    Ich hab hier VS 2010 Premium das sollte doch schon die Suite mit sämtlichen Funktionen sein?

    @knivil
    Wie stellst du dir das vor?



  • Sind Default-Templateargumente für Funktionstemplates in C++0x? Falls ja, werden sie von Visual Studio eben noch nicht unterstützt...



  • Das behauptet zumindest der GCC. Ich hab mich nicht weiter damit beschäftigt. Wüsste allerdings nicht, warum man das praktische Feature raus lassen sollte? Ich geh mal davon aus, dass es einen Unterschied zwischen den C++0x Schaltern gibt. Es gibt da nämlich extra einen mit GNU-Präffix/Suffix. Ich hab den ohne genutzt und der wurde auch empfohlen.



  • Ich hab das jetzt so gelöst:

    template<typename T>
    void foo(T const & v)
    {
      foo_impl<sizeof(T)>(reinterpret_cast<AByte const * const>(&v));
    }
    

    AByte ist einfach nur ein unsigned char.
    Was mir aber nicht so gefällt ist der Cast. Ich schätze aber für das Problem gibt es sonst keine elegante Variante? In foo_impl werden die einzelnen Bytes des Typs gebraucht.


  • Mod

    Übergib doch einen void*.

    Und wenn du da jetzt keine Spezialisierung für bestimmte Größen machst, dann hau ich dich (und Nexus haut dich noch viel fester).



  • SeppJ schrieb:

    Übergib doch einen void*.

    Naja, dann muss ich in den einzelnen Funktionen casten. Das wäre im Endeffekt nur mehr Aufwand.

    Edit:
    Ich hab grad nochmal den Originalcode raus gekrammt, dass hat durchaus seinen Sinn, über eine Switch-Anweisung in die Funktionen zu gehen. Weil diese als Eingabe und Ausgabe einen Typ haben, der die selbe Datenbreite hat.



  • Zuerst hattest du T , dann wolltest du nur sizeof(T) und jetzt bist du an den einzelnen Bytes interessiert? Überhaupt werde ich wohl nie verstehen, was dein eigentliches Anliegen war...



  • @OP: Sag uns doch bitte, was du erreichen willst, und nicht, womit du das erreichen willst (nämlich mit irgendwelchen abstrusen template-verunstaltungen).

    Dein ursprüngliches Problem (gewürzt mit ein wenig erklärendem Quellcode) wird sicherlich kein Staatsgeheimnis sein.



  • Wie würdet ihr eine Byteswapping-Funktion implementieren? Falls es da eine Standardfunktion für gibt, bitte auch nennen. Ich hab die paar Zeilen nur lieber schnell selbst geschrieben, weil ich nichts passendes in kürzerer Zeit gefunden habe. Meine Frage bezog sich nur darauf, ob es eleganter geht. Meine Frage hat sich also somit geklärt. Auch weil noch ein paar Details dazu gekommen sind, die andere Anforderungen überflüssig gemacht haben. Außer jemand hat generell noch einen Vorschlag, wie man eine Byteswap-Funktion realisieren sollte. Bitte nicht die htonX()-Funktionen nennen, die swappen nämlich nur, wenn es notwendig ist.



  • Dreieckstausch mit memcpy() ? Dass das Verhalten von byteweisen Operationen nur für PODs definiert ist, brauch ich wohl nicht zu sagen...



  • Nexus schrieb:

    Dreieckstausch mit memcpy() ?

    Beispiel, bitte?

    Nexus schrieb:

    Dass das Verhalten von byteweisen Operationen nur für PODs definiert ist, brauch ich wohl nicht zu sagen...

    Nein, ist klar.


Anmelden zum Antworten