Genau eine Funktion zum umwandeln von std::vector<unsigned char> in integralen Datentyp?



  • Ist das sinnvoll? Könnte man natürlich über templates tun, der algorithmus ist immer der selbe, jedoch würde ich dann gerne verhindern das "sinnlose" Datentypen, also nicht integrale, als Parameter eingesetzt werden.
    Wie würde ich das am besten machen?
    Prinzipiell geht das ja wie folgt:

    ByteToInt(const std::vector<quint8>& source,quint32& offset,quint16& output)
    {
        output = 0;
        for(quint8 i = 0; i < sizeof(quint16);++i)
            output += (source[offset+i] << (sizeof(quint16)-(i+1))*8;
    }
    

    Aber das müsste ich ja für jeden Datentyp spezialisieren 😕



  • Fragen zur Funktion:

    ByteToInt(const std::vector<quint8>& source,quint32& offset,quint16& output) 
    { 
        output = 0; 
        for(quint8 i = 0; i < sizeof(quint16);++i) 
            output += (source[offset+i] << (sizeof(quint16)-(i+1))*8; 
    }
    
    • Ist das eine Konstruktordefinition in der Klasse? Oder was?
    • Wieso sizeof(quint16) ? Die Größe von quint16 ist doch schon durch den Namen impliziert: 2
    • Wieso nimmst du eine Referenz für den Parameter offset ?


  • Jetzt habe ich verstanden, worauf du hinaus willst! 💡

    Wie würde ich das am besten machen?

    Da gibt es verschiedene Möglichkeiten.
    Ich würde einfach über std::enable_if / static_assert (mit std::is_integral als Kondition) gehen. :xmas2:

    Also

    template<typename Int>
    typename std::enable_if< std::is_integral<Int>::value, Int>::type 
    ByteToInt(const std::vector<quint8>& source,quint32& offset,quint16& output) 
    { 
        output = 0; 
        for(quint8 i = 0; i < sizeof(quint16);++i) 
            output += (source[offset+i] << (sizeof(quint16)-(i+1))*8; 
    }
    

    Bzw. mit C++11

    template<typename Int>
    Int ByteToInt(const std::vector<quint8>& source,quint32& offset,quint16& output) 
    { 
        static_assert( std::is_integral<Int>::value, "Has to be an integral type!");
        output = 0; 
        for(quint8 i = 0; i < sizeof(quint16);++i) 
            output += (source[offset+i] << (sizeof(quint16)-(i+1))*8; 
    }
    

    Nicht vergessen, <type_traits> einzubinden!



  • was es nicht alles gibt im standard^^ danke, werds ausprobieren 🙂



  • achso, das sizeof(quint16) hatte ich nur wegen IMO erhöhter Klarheit geschrieben, ist natürlich immer 2 byte, aber finde es so leicht besser.



  • Namenloser324 schrieb:

    achso, das sizeof(quint16) hatte ich nur wegen IMO erhöhter Klarheit geschrieben, ist natürlich immer 2 byte, aber finde es so leicht besser.

    Ist auch gut so, lass des dort so stehen. Siehe: http://www.c-plusplus.net/forum/p2283257#2283257



  • Sone schrieb:

    Jetzt habe ich verstanden, worauf du hinaus willst! 💡

    Wie würde ich das am besten machen?

    Da gibt es verschiedene Möglichkeiten.
    Ich würde einfach über std::enable_if / static_assert (mit std::is_integral als Kondition) gehen. :xmas2:

    Also

    template<typename Int>
    typename std::enable_if< std::is_integral<Int>::value, Int>::type 
    ByteToInt(const std::vector<quint8>& source,quint32& offset,quint16& output) 
    { 
        output = 0; 
        for(quint8 i = 0; i < sizeof(quint16);++i) 
            output += (source[offset+i] << (sizeof(quint16)-(i+1))*8; 
    }
    

    Bzw. mit C++11

    template<typename Int>
    Int ByteToInt(const std::vector<quint8>& source,quint32& offset,quint16& output) 
    { 
        static_assert( std::is_integral<Int>::value, "Has to be an integral type!");
        output = 0; 
        for(quint8 i = 0; i < sizeof(quint16);++i) 
            output += (source[offset+i] << (sizeof(quint16)-(i+1))*8; 
    }
    

    Nicht vergessen, <type_traits> einzubinden!

    Sooo, habs jetzt probiert und funktioniert, vielen lieben Dank 🙂
    Vieeeel kompakter jetzt^^
    Wobei die Fehlermeldung die ich erhalte, wenn ich testweise einen nicht integralen Typen als Typ wähle seltsam ist:

    Ungültige explizite template-Argumente für "void ByteToInt(const std::vector<_Ty> &,unsigned int &,std::enable_if<std::tr1::is_integral<_Ty>::value,Int>::type &)".
             with
     [
                  _Ty=unsigned char
              ]
    

    Denn ich deklarierte die Funktion wie folgt:

    template<typename Int>
    void ByteToInt(const std::vector<unsigned char>& source,unsigned int& offset,typename std::enable_if< std::is_integral<Int>::value, Int>::type& output)
    

    Also vector<unsigned char> und nicht vector<Int>, wieso gibt er das dennoch als Fehler aus?

    achso und hierzu "Wieso nimmst du eine Referenz für den Parameter offset? ":
    Nutze das mehrfach hintereinander und finde es bequemer wenn die Funktion den offset mit dem lesen mitverschiebt, damit ich nicht zwischen zwei lesevorgängen den offset ändern muss. Glaube ich ändere das aber in nen iterator 😕 Das ist noch bequemer.


  • Mod

    Namenloser324 schrieb:

    ich deklarierte die Funktion wie folgt:

    template<typename Int>
    void ByteToInt(const std::vector<unsigned char>& source,unsigned int& offset,typename std::enable_if< std::is_integral<Int>::value, Int>::type& output)
    

    Dann musst du das Templateargument explizit angeben, das ist so nicht deduzierbar.



  • camper schrieb:

    Namenloser324 schrieb:

    ich deklarierte die Funktion wie folgt:

    template<typename Int>
    void ByteToInt(const std::vector<unsigned char>& source,unsigned int& offset,typename std::enable_if< std::is_integral<Int>::value, Int>::type& output)
    

    Dann musst du das Templateargument explizit angeben, das ist so nicht deduzierbar.

    @TE: Deswegen macht man das meistens mit dem Rückgabewert.



  • Geh doch bitte weg mit deinem enable_if-Crap, Hacker.



  • Wie würdest du es denn lösen, Kellerautomat?(ernst gemeinte Frage)



  • Ich wuerde es einfach krachen lassen. Die Funktion aus dem Overload-Set zu schmeissen fuehrt mit Sicherheit zu einer schrecklichen Fehlermeldung.
    Ausserdem funktionierts dann auch wenigstens mit meiner BigInt Klasse.



  • Kellerautomat schrieb:

    Geh doch bitte weg mit deinem enable_if-Crap, Hacker.

    Nein.

    Kellerautomat schrieb:

    Ich wuerde es einfach krachen lassen. Die Funktion aus dem Overload-Set zu schmeissen fuehrt mit Sicherheit zu einer schrecklichen Fehlermeldung.

    Ja, abgesehen von dem Fakt das wir hier nichts aus der overload resolution entfernen.

    Kellerautomat schrieb:

    Ausserdem funktionierts dann auch wenigstens mit meiner BigInt Klasse.

    Genau. 😮
    Denn der TE hat ja auch auf irgendeine Weise suggeriert, dass er irgendetwas anderes als quint16 und Konsorten nutzen wird.

    Main Gott, wozu diese verdammte Allgemein-Stil bei Kleinigkeiten....



  • Sone schrieb:

    Ja, abgesehen von dem Fakt das wir hier nichts aus der overload resolution entfernen.

    Overload Set.
    Doch, genau das tut SFINAE.

    Sone schrieb:

    Main Gott, wozu diese verdammte Allgemein-Stil bei Kleinigkeiten....

    Main <<< Gott, warum immer dieses Verkomplizieren, wenn die einfache Version allgemeiner ist.

    Du bist ein Idiot. Und nun sei still.



  • Overload Set.
    Doch, genau das tut SFINAE.

    Mir geht es nicht um das overload-set.
    Denn es ist klar, dass es daraus entfernt wird, sobald es einen Fehler bei der Instantiierung gibt.

    Es geht mir darum, dass der TE doch nicht mal irgendwie angedeutet hat, dass es eine zweite Funktion(-stemplate) gleichen Namens gibt.

    Also wird es auch nicht vom Compiler hundert Zeilen hageln, sondern eben nur eine -und das ist in Ordnung.



  • Und genau das ist das Problem, bist du irgendwie dumm oder so? Ein Fehlermeldung 'no matching function call' verwirrt erstmal den User, waehrend ein Template-Stack an Fehlermeldungen wenigstens nuetzliche Information enthaelt.



  • Kellerautomat schrieb:

    Und genau das ist das Problem, bist du irgendwie dumm oder so?

    Nein, danke der Nachfrage.

    Kellerautomat schrieb:

    Ein Fehlermeldung 'no matching function call' verwirrt erstmal den User

    Nein. Wenn direkt darunter steht, dass enable_if< std::is_integral<~>::value > kein Member-Typedef enthält, wird jedem klar, dass der übergebene Typ invalid ist.

    Kellerautomat schrieb:

    , waehrend ein Template-Stack an Fehlermeldungen wenigstens nuetzliche Information enthaelt.

    Blödsinn, der ist erst recht verwirrend.



  • Sone schrieb:

    Kellerautomat schrieb:

    Ein Fehlermeldung 'no matching function call' verwirrt erstmal den User

    Nein. Wenn direkt darunter steht, dass enable_if< std::is_integral<~>::value > kein Member-Typedef enthält, wird jedem klar, dass der übergebene Typ invalid ist.

    Das steht da nicht, weil es KEIN FEHLER IST. SFINAE.

    Kellerautomat schrieb:

    , waehrend ein Template-Stack an Fehlermeldungen wenigstens nuetzliche Information enthaelt.

    Blödsinn, der ist erst recht verwirrend.[/quote]
    Fuer deine Begrenzte Kapazitaet vielleicht.



  • Kellerautomat schrieb:

    ..

    Man, dass ich das jetzt machen muss...
    Simples Beispiel:

    #include <iostream>
    
    template<typename T>
    typename std::enable_if<std::is_integral<T>::value>::type foo() {}
    
    int main() /// Du benutzt keine Kommandozeilenparameter, weg damit
    {
        foo<void>();
    }
    

    G++ 4.8 schrieb:

    TEMP2.cxx||In function 'int main()':|
    TEMP2.cxx|8|error: no matching function for call to 'foo()'|
    TEMP2.cxx|8|note: candidate is:|
    TEMP2.cxx|4|note: template<class T> typename std::enable_if<std::is_integral<_Tp>::value>::type foo()|
    TEMP2.cxx|4|note: template argument deduction/substitution failed:|
    TEMP2.cxx|8|required from here|
    TEMP2.cxx|4|error: no type named 'type' in 'struct std::enable_if<false, void>'

    Du springst zu der stelle, und siehst, welche Kondition dein Typ nicht erfüllen kann. Fertig.

    Fuer deine Begrenzte Kapazitaet vielleicht

    Weder ist meine Kapazität begrenzt, noch ist der Stack dann übersichtlich, wenn als "Notiz" gleich das ganze Overload-Set präsentiert wird. Beispiel: Stream-Operatoren.



  • http://ideone.com/TUlxLw

    Wie auch immer, die Fehlermeldung ist in beiden Faellen Humbug.



  • Kellerautomat schrieb:

    http://ideone.com/TUlxLw

    Wie auch immer, die Fehlermeldung ist in beiden Faellen Humbug.

    was ist denn an der fehlermeldung nicht eindeutig ??


Anmelden zum Antworten