Genau eine Funktion zum umwandeln von std::vector<unsigned char> in integralen Datentyp?
-
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 überstd::enable_if/static_assert(mitstd::is_integralals 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.
-
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 alsquint16und 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.
-
Wie auch immer, die Fehlermeldung ist in beiden Faellen Humbug.
-
Kellerautomat schrieb:
Wie auch immer, die Fehlermeldung ist in beiden Faellen Humbug.
was ist denn an der fehlermeldung nicht eindeutig ??
-
Was genau /ist/ denn daran eindeutig? Absolut /nichts/ deutet darauf hin, dass T kein integraler Typ ist.
-
Mit neueren Compilern wird es besser:
g++-4.6.3 schrieb:
test.cpp: In function ‘int main()’:
test.cpp:9:14: error: no matching function for call to ‘foo()’
test.cpp:9:14: note: candidate is:
test.cpp:4:41: note: template<class T> typename std::enable_if<false, T>::type foo()g++-4.7.2 schrieb:
test.cpp: In function ‘int main()’:
test.cpp:9:14: error: no matching function for call to ‘foo()’
test.cpp:9:14: note: candidate is:
test.cpp:4:41: note: template<class T> typename std::enable_if<false, T>::type foo()
test.cpp:4:41: note: template argument deduction/substitution failed:
test.cpp: In substitution of ‘template<class T> typename std::enable_if<false, T>::type foo() [with T = int]’:
test.cpp:9:14: required from here
test.cpp:4:41: error: no type named ‘type’ in ‘struct std::enable_if<false, int>’g++-4.8.0 schrieb:
test.cpp: In function ‘int main()’:
test.cpp:9:14: error: no matching function for call to ‘foo()’
foo<int>();
^
test.cpp:9:14: note: candidate is:
test.cpp:4:41: note: template<class T> typename std::enable_if<false, T>::type foo()
typename std::enable_if<false, T>::type foo()
^
test.cpp:4:41: note: template argument deduction/substitution failed:
test.cpp: In substitution of ‘template<class T> typename std::enable_if<false, T>::type foo() [with T = <missing>]’:
test.cpp:9:14: required from here
test.cpp:4:41: error: no type named ‘type’ in ‘struct std::enable_if<false, int>’clang++ 3.2 schrieb:
test.cpp:9:5: error: no matching function for call to 'foo'
foo<int>();
^~~~~~~~
test.cpp:4:25: note: candidate template ignored: disabled by 'enable_if' [with T = int]
typename std::enable_if<false, T>::type foo()
^
1 error generated.
-
Kellerautomat schrieb:
Was genau /ist/ denn daran eindeutig? Absolut /nichts/ deutet darauf hin, dass T kein integraler Typ ist.
dann benutzt man seine augen und seinen kopf und schaut sich die zeile mal an, wo der fehler auftritt und man schaut sich die funktion an. mit ner ide sind das ca. 10-20 sek.
-
Deine Einstellung ist dumm. Aber offenbar ist Dummheit hier zum Massenphaenomen geworden, daher spar ich mir die /dumme/ Diskussion mal.
-
ja spar sie dir, wenn du es eh besser weißt, warum ein template stack oder ähnliches http://ideone.com/QTH9mG ausekräftiger, besonders für einen anfänger besser zu verstehen, sein soll, als die fehlermerldung beim enable_if, würde ich dann schon gerne wissen. wenn du hierfür ein gutes und überzeugendes argument liefern kannst, würde mich das schon freuen, zumindest mehr als deine unkonstruktiven beleidigungen.