Genau eine Funktion zum umwandeln von std::vector<unsigned char> in integralen Datentyp?
-
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.
-
Kellerautomat schrieb:
Deine Einstellung ist dumm. Aber offenbar ist Dummheit hier zum Massenphaenomen geworden, daher spar ich mir die /dumme/ Diskussion mal.
Wenn jemand eine Zeile Code schreibt, erwarte ich von diesem jemand ein gewisses Verständnis für diese Zeile.
Wenn jemand ein Funktionstemplate instantiieren lässt, dann müssen ihm die Bedingungen und die Verwendungsweise völlig klar sein. Sprich: Es geht hier nicht darum, ein Funktionstemplate zu schreiben das beim ausprobieren eine tolle Fehlermeldung wirft. Sondern eines, dass einfach nur mit einem bestimmten Typ instantiiert werden darf. Dafür istenable_ifda.
Braucht man eine ordentliche Fehlermeldung, nimmt manstatic_assert/BOOST_STATIC_ASSERT.Es geht darum, dass man das Nutzen eines bestimmten Typs einfach verbietet.
Weil es Fälle gibt, wo dann eine syntaktisch korrekte Funktion instantiiert wird, diese aber dank falschem Typ möglicherweise völligen Scheiß macht - der User aber keine Ahnung hat. Den Fall, dass enable_if irgendetwas nicht zulässt, sollte ein ordentlicher Programmierer sowieso niemals haben. Hatte ich bis jetzt auch noch nie.
-
vario-500 schrieb:
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.
Natuerlich ist das aussagekraeftiger, mach die Augen auf.
prog.cpp: In function 'void foo(T, T) [with T = std::vector<int>]':
prog.cpp:9:71: instantiated from here
prog.cpp:5:4: error: no match for 'operator+' in 't1 + t2'Hier steht /ganz genau/, was das Problem ist, naemlich, dass es keinen operator+ gibt.
Sone schrieb:
Wenn jemand eine Zeile Code schreibt, erwarte ich von diesem jemand ein gewisses Verständnis für diese Zeile.
Wenn jemand ein Funktionstemplate instantiieren lässt, dann müssen ihm die Bedingungen und die Verwendungsweise völlig klar sein. Sprich: Es geht hier nicht darum, ein Funktionstemplate zu schreiben das beim ausprobieren eine tolle Fehlermeldung wirft. Sondern eines, dass einfach nur mit einem bestimmten Typ instantiiert werden darf. Dafür istenable_ifda.
Braucht man eine ordentliche Fehlermeldung, nimmt manstatic_assert/BOOST_STATIC_ASSERT.Erstens spricht nichts dagegen, das Template mit meiner Bigint Klasse zu instanzieren, ausser dass /du/ mich mit deinem enable_if Schrott daran hinderst. (Mit einem Concept waere das absolut legitim)
Und zweitens habt ihr alle beide den Zweck von enable_if nicht verstanden. enable_if ist in erster Linie /nicht/ dazu da, Instanzierung eines Templates zu verhindern, und einen Fehler zu erzeugen. enable_if ist dazu da, bei mehreren Overloads /gezielt/ bestimmte Overloads aus dem Overload-Set zu schmeissen, weil sie etwas falsches tun wuerden, bei Overload Resolution beforzugt wuerden, aber einen Fehler erzeugen wuerden, etc.
Fuer deinen Fall ist, wie du bereits richtig erkannt hast, static_assert zu verwenden. Aber dann mach auch bitte einen ordentlichen Check, ob T einen passenden operator + hat.