Schwierigkeiten mit templates
-
Cool, so klappt es..!

Damit ich´s richtig verstehe:
Damit haben wir jetzt eine überladene Template-Funktion und der Compiler sucht sich die richtige raus, je nach dem ob´s ein string Vektor ist, oder ein anderer..?@Skym0sh0
Danke für die Erkärung..!
-
ja, wobei ich die funktion mit dem string als template spezialisieren würde, was Sone in seinem beitrag nicht gemacht hat
mit änderung:
template<typename T> std::istream& readFrom(std::istream& is, T & toread) { return is >> toread; } template<> std::istream& readFrom(std::istream& is, std::string & toread) { return std::getline(is, toread); }nicht dass dann probleme bei überladung oder überdeckung gibt...
-
Skym0sh0 schrieb:
template<>
std::istream& readFrom(std::istream& is, std::string & toread)
{
return std::getline(is, toread);
}
[/cpp]nicht dass dann probleme bei überladung oder überdeckung gibt...
Deine Version ist so eigentlich falsch.
template<> std::istream& readFrom<std::string>(std::istream& is, std::string & toread) { return std::getline(is, toread); }Und meine ist vollkommen korrekt und leichter zu lesen, denn es ist eine Überladung; für den Compiler stehen non-template functions an erster Stelle, danach kommen erst Template-Funktionen.
Außerdem kennt jeder die Regel: Templatefunktions-Spezialisierungen sind schlecht, sie überladen nicht.
-
..ui..da komm ich so langsam nicht mehr mit.
Könnt ihr das vielleicht näher erklären..? ..oder mir was zu lesen geben..?

Es geht um den Unterschied zwischen
std::istream& readFrom<std::string>(std::istream& is, std::string & toread)und
std::istream& readFrom(std::istream& is, std::string & toread)oder..?
Mal so nebenbei, warum ist mein eingebetteter Code eigentlich nur schwarz/weiß..?

-
jetzt in den letzten beispielen hast du keine schlüsselworte und nur die werden farblich herausgehoben, bei anderen code snippets von dir hattest du Code statt Cpp tags verwendet
ok, mit den templates komme ich langsam auch nicht mehr so mit.
ich, mit meiner intuition, würde das template so schreiben wie vorgeschlagen. und es dann für std::string weiter spezialisieren
ich habs auch grad mal getestet (VC2010 unter Win7 64), da klappt sowohl die überladung neben dem template und der spezialisierung
#include <iostream> template<typename T> T maximum(T const& a, T const& b) //template { return a<=b ? b : a; } template<> float maximum<float>(float const& a, float const& b) //spezialisiertes template // oder // float maximum(float const& a, float const& b) geht auch! { std::cout << "Template Spez" << std::endl; if ( a < b ) return b; else return a; } float maximum(float const& a, float const& b) // normale funktion { std::cout << "Non-Template" << std::endl; if ( a < b ) return b; else return a; } int main(int argc, char * argv[]) { std::cout << maximum(4355.0f, 7.0f) << std::endl; // ruft die normale funktion auf std::cout << maximum<float>(4355.0f, 7.0f) << std::endl; // ruft die template spez auf std::cout << maximum(4355.0, 7.0) << std::endl; // ruft maximum<double> auf, also das template return 0x0; }
-
template <typename T1, typename T2> auto max(T1 t1, T2 t2) -> decltype(t1 > t2 ? t1 : t2) { return t1 > t2 ? t1 : t2; }
-
hehe^^
genausowas meine ich, das kommt raus wenn wer was sagt, der ahnung hat

-
Kellerautomat schrieb:
template <typename T1, typename T2> auto max(T1 t1, T2 t2) -> decltype(t1 > t2 ? t1 : t2) { return t1 > t2 ? t1 : t2; }Wie kann das überhaupt für nicht konstante Ausdrücke kompilieren (tut es, aber wieso)?

-
Kellerautomat schrieb:
template <typename T1, typename T2> auto max(T1 t1, T2 t2) -> decltype(t1 > t2 ? t1 : t2) { return t1 > t2 ? t1 : t2; }Tja, nein; obwohl das kompiliert wird, ist es eigentlich Schwachsinn.
Der Rückgabewert der Funktion ist immer gleich (edit also bei gleichen Template-Parametern).Ist wohl ein Compilerbug.
-
Wieso sollte das nicht funktionieren?
PS:
decltype ist wie sizeof
der wert von t1/t2 wird nicht evaluiert - nur der Ausdruck wird auf seinen Typ hin überprüft.
PPS:
bei int und double wird ja nicht manchmal int und manchmal double returned sondern immer double.
-
Shade Of Mine schrieb:
bei int und double wird ja nicht manchmal int und manchmal double returned sondern immer double.
Ach, da wird einfach direkt wie
sizeofbehandelt? Ist mir aufgefallen. Aber ich dachte, dass wär' ja bescheuert- ich meine, wenn man t1 < t2 schreibt dann erwarte ich dass das entsprechend ausgewertet wird...
Aber wenn nur die Größen der Typen behandelt werden, dann macht die Funktion keinen Sinn, es sei denn, es soll einfach der größere Typ zurückgegeben werden.
-
Sone schrieb:
Shade Of Mine schrieb:
bei int und double wird ja nicht manchmal int und manchmal double returned sondern immer double.
Ach, da wird einfach direkt wie
sizeofbehandelt? Ist mir aufgefallen. Aber ich dachte, dass wär' ja bescheuert- ich meine, wenn man t1 < t2 schreibt dann erwarte ich dass das entsprechend ausgewertet wird...
Wird es ja auch - aber eben nicht vom Wert her.
Bei sizeof wird ja auch nicht der Ausdruck auf den Wert aufgelöst, sondern auf den Typ(und dann größe). decltype liefert dir den Typ eines Ausdrucks.decltype(5*5) würde dir ja auch nicht 10 liefern sondern int

-
Bevor ich eine genauere Erklärung gebe, möchte ich dir eine Frage stellen. Vielleicht hilft dir das, zu verstehen, wie mein max funktioniert.
int a = 2, b = 3; double c = 4., d = 1.; auto e = a > c ? a : c; auto f = b > d ? b : d;Von welchem Typ sind e und f?

-
double
weil das muss zur compilezeit ausgewertet werden, aber der ausdruck selbst wird nicht unbedingt (kann duch optimierungen oder sowas schon) ausgewertet. sprich der compiler sucht nach einem kompromiss, was für beides geht. und da ein int implizit nach double castable ist ---> double
-
War eigentlich an Sone gerichtet, hätte ich dazuschreiben sollen. Aber ja, das ist korrekt.
-
ok, weil ich wusste es auch nicht bestimmtheit und wollte es mal testen

kann man in dem forum so ne art spoiler funktion nutzen?
-
Skym0sh0 schrieb:
kann man in dem forum so ne art spoiler funktion nutzen?
Nein, das wäre in einem Programmierfachforum keine häufig genutzte Funktion. Du kannst so etwas emulieren, indem du einen Link zu Pastebin, ideone oder ähnlichem benutzt, dem ein Leser dann optional folgen kann oder nicht.
-
Skym0sh0 schrieb:
kann man in dem forum so ne art spoiler funktion nutzen?
rot13 verschlüsseln

wir sind hier unter programmierern
-
Ich hab es schon durch Shades Beitrag verstanden. Ich wusste auch schon, dass die Ausdrücke nicht ausgewertet werden :), denn auch ich verwende
decltype()oft. Nur, dachte ich, ist es so, dass hier entschieden wird, welcher Typ zurückgegeben wird, anhand der Werte der Variablen
Wenn ich es jetzt richtig verstanden habe, dann kannst du aber auch gleich
template <typename T1, typename T2> typename std::common_type<T1, T2>::type max(T1 t1, T2 t2) { return t1 > t2 ? t1 : t2; }schreiben, oder?
-
Sone schrieb:
std::common_type<T1, T2>::type
Ja.
Sofern common_type das korrekte macht. Ich denke ja, habe es aber noch nie verwendet.
Das coole and decltype ist, dass es direkt den Code widerspiegelt. So ist zB
declytpe(char(1)*char(1)) == int
während common_type<char, char>::type == char wäre.In diesem Fall wäre common_type OK, aber das sollte man dennoch im Hinterkopf behalten.