wie spezialisierung einer bestimmten funktion
-
hola leute
hab da ein kleines problem mit einer spezialisierung.
hab derzeit foilgenden code:
template <class T> unsigned int WriteToStream(char *stream, const T &t) { if(is_pod<T>::type) /* liefert true wenn T ein bestimmter datentyp ist */ return write_to_stream(stream, t); else return write_to_stream_ex(stream, t); }ich schaetz mal das sogar der bcb in diesem fall je nach datentyp schon zur compile-zeit die richtige funktion (write_to_stream) auswaehlt. jedoch bekomme ich bei der funktion immer die stoerenden warnungen:
'bedingung immer true' oder 'bedingung immer false' oder 'code wird nie erreicht'.
jetzt dachte ich, das ich das vielleicht ueber eine spezialisierung machen koennte. aber irgendwie schaffe ich das nicht.
write_to_stream(_ex) sieht folgend aus:template <class T> unsigned int write_to_stream(char *stream, const T &t) { ... } template <class T> unsigned int write_to_stream_ex(char *stream, const T &t) { ... }ich dachte nun das ich write_to_stream einfach spezialisiere:
template <class T, bool b> unsigned int write_to_stream(char *stream, const T &t); template <> unsigned int write_to_stream<class T, true>(char *stream, const T &t) { ... }aber scheinbar funktioniert das nicht ganz so wie ich mir das vorgestellt habe.
kann das ueberhaupt so funktionieren wie ich mir das vorstelle ? oder muss ich da einen anderen weg einschlagen ?Meep Meep
-
zeig mal die implementierung von is_pod
...
is_pod<T>::type in der if abfrage sieht ein bischen komisch aus
-
kann das ueberhaupt so funktionieren wie ich mir das vorstelle ?
Nein. Da man Funktionstemplates nicht partiell spezialisieren kann. Du kannst aber mit Überladung das Gewünschte erreichen:
template <int> struct Int2Type {}; // Für Non-Pods template <class T> unsigned int write_to_stream(char *stream, const T &t, Int2Type<0>) { // ... } // Für Pods template <class T> unsigned int write_to_stream(char *stream, const T &t, Int2Type<1>) { // ... } template <class T> unsigned int WriteToStream(char *stream, const T &t) { return write_to_stream(stream, t, Int2Type<is_pod<T>::type>()); }
-
re
danke fuer die hilfe. auf die moeglichkeit der ueberladung bin ich nicht gekommen.
Cpt. Tanga schrieb:
zeig mal die implementierung von is_pod
...
is_pod<T>::type in der if abfrage sieht ein bischen komisch auswarum ?
Meep Meep
-
wär nicht is_pod<T>::value logischer?
HumeSikkins schrieb:
kann das ueberhaupt so funktionieren wie ich mir das vorstelle ?
Nein. Da man Funktionstemplates nicht partiell spezialisieren kann. Du kannst aber mit Überladung das Gewünschte erreichen:
oder du baust dir einen funktor und spezialisierst diesen partiell. falls du sowieso einen brauchst (bzw. brauchen könntest) um ihn mit irgendwelchen algorithmen zu verwenden, ist das der elegantere weg. überladung ist praktischer (wobei ich heir noch SFINAE mittels enable_if benutzen würde, schliesslich soll die selektion ja automatisch erfolgen), falls du keine funktoren brauchst.
-
re
hoi camper
wie wuerde das mittels partiell spezialisierten functor ausssehen ?
koenntest du mir das anhand eines beispiels mal zeigen ?
enable_if is aus der boost-library ?Meep Meep
-
mit funktor:
//allgemein: template<class T, bool pod_opt> struct write_to_stream { unsigned operator()(char* stream, const T& t) const { // ... } }; // für pods: template<class T> struct write_to_stream<T,true> { unsigned operator()(char* stream, const T& t) const { // ... } }; template <class T> unsigned int WriteToStream(char *stream, const T &t) { return write_to_stream<T,is_pod<T>::value>()(stream, t); }per überladung (ja mit boost::enable_if, ich lasse jetzt mal boost:: weg):
// Für Non-Pods template <class T> unsigned int WriteToStream(char *stream, const T &t, typename disable_if_c<is_pod<T>::value>::type* = 0) { // ... } // Für Pods template <class T> unsigned int WriteToStream(char *stream, const T &t, typename enable_if_c<is_pod<T>::value>::type* = 0) { // ... }
-
Bist du dir 100%ig sicher das du sowas brauchst?
-
re
die functorvariante is auch recht interessant. aber ich versteh da etwas nicht.
weshalb funktioniert bei ner struct die part.spezialisierung <T, true> und bei ner funktion nicht ?
und noch was:template <class T> unsigned int WriteToStream(char *stream, const T &t) { return write_to_stream<T,is_pod<T>::value>()(stream, t); } ??wieso steht ueber den ?? eine leere klammer ? irgendwie steh ich da auf der leitung
Meep Meep
-
Die leere Klammer stellt den Constructor Aufruf da. Aber ich würde einfach Humes Methode bevorzugen.
@Sinn
Natürlich braucht man solche Dinge. So kann man zB. sinnvoll optimieren oä.
-
Ach ist doch alles nur Frickelei.

-
9 schrieb:
Ach ist doch alles nur Frickelei.

Nö, ist nur eine neue Methode zu denken, daran muss man sich eben erst gewöhnen.