 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Boris Guest
|
Posted: Fri Oct 29, 2004 12:56 pm Post subject: Statische Polymorphie |
|
|
Hallo,
ich möchte gerne statische Polymorphie nutzen, da zur Laufzeit klar
ist, welche Klasse benutzt wird. Ich habe also 4 Klassen (A, B, C, D)
welche eine Methode
double getx();
haben. Nun habe ich eine Funktion "mache"
template <typename T>
void mache (const T& t){
....
x = t.getx();
}
Diese Funktion habe ich aber auch für den Typ double
void mache (const double& t){
....
x = t;
}
Wenn ich nun folgenden Aufruf mache, gibt der Compiler einen Fehler:
mache (1); //Error
mache (1.1); //OK
Der Grund ist mir klar, er findet keine Methode für int, benutzt also
die template Variante, int hat aber keine Methode getx() => Fehler.
Wie kann ich OHNE für jeden Typ eine Methode "mache" zu schreiben das
Problem lösen? Ich möchte aus Performacegründen auch keine virtuellen
Funktionen benutzen.
Über Lösungsideen bin ich dankbar,
Boris
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Thomas Mang Guest
|
Posted: Fri Oct 29, 2004 2:44 pm Post subject: Re: Statische Polymorphie |
|
|
"Boris" <vonloesch (AT) gmail (DOT) com> schrieb im Newsbeitrag
news:41a2e2dc.0410290456.2072653f (AT) posting (DOT) google.com...
| Quote: | Hallo,
ich möchte gerne statische Polymorphie nutzen, da zur Laufzeit klar
ist, welche Klasse benutzt wird. Ich habe also 4 Klassen (A, B, C, D)
welche eine Methode
double getx();
haben. Nun habe ich eine Funktion "mache"
template <typename T
void mache (const T& t){
...
x = t.getx();
}
Diese Funktion habe ich aber auch für den Typ double
void mache (const double& t){
...
x = t;
}
Wenn ich nun folgenden Aufruf mache, gibt der Compiler einen Fehler:
mache (1); //Error
mache (1.1); //OK
Der Grund ist mir klar, er findet keine Methode für int, benutzt also
die template Variante, int hat aber keine Methode getx() => Fehler.
Wie kann ich OHNE für jeden Typ eine Methode "mache" zu schreiben das
Problem lösen? Ich möchte aus Performacegründen auch keine virtuellen
Funktionen benutzen.
|
Ich sehe Lösungen:
a) Du änderst die template - Funktion so um, daß sie das macht was Deine
jetztige double-Version macht - also kein getx aufrufen.
Stattdessen schreibst Du 4 Überladungen für A, B, C und D, wo Du getx
aufrufst.
Macht insgesamt 5 Funktionen.
b) Du benutzt "type-traits".
Siehe boost-type_traits, womit Du eine template-Spezialisierung für die
eingebauten Typen aufrufen kannst, die dann eben nicht getx aufruft.
Alternativ kannst Du auch eine traits-Klasse für A, B, C und D schreiben,
und dann Deine Funktion darauf spezialisieren.
Wenn Dir diesbezüglich was unklar ist, google einfach oder frage hier nach..
Thomas
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Torsten Robitzki Guest
|
Posted: Fri Oct 29, 2004 2:49 pm Post subject: Re: Statische Polymorphie |
|
|
Boris wrote:
| Quote: | Hallo,
ich möchte gerne statische Polymorphie nutzen, da zur Laufzeit klar
ist, welche Klasse benutzt wird. Ich habe also 4 Klassen (A, B, C, D)
welche eine Methode
double getx();
haben. Nun habe ich eine Funktion "mache"
template <typename T
void mache (const T& t){
...
x = t.getx();
}
Diese Funktion habe ich aber auch für den Typ double
void mache (const double& t){
...
x = t;
}
Wenn ich nun folgenden Aufruf mache, gibt der Compiler einen Fehler:
mache (1); //Error
mache (1.1); //OK
Der Grund ist mir klar, er findet keine Methode für int, benutzt also
die template Variante, int hat aber keine Methode getx() => Fehler.
Wie kann ich OHNE für jeden Typ eine Methode "mache" zu schreiben das
Problem lösen? Ich möchte aus Performacegründen auch keine virtuellen
Funktionen benutzen.
|
Hm, ich bin mir nicht ganz sicher verstanden zu haben, was Du möchtest.
Vielleicht möchtest Du einen allgemeinen Fall und einen für alle Typen,
für die es eine Konvertierung nach double gibt unterscheiden. Dann würde
ich es auch so formulieren. Bleibt also die Aufgabe, festzustellen, ob
ein Typ in ein double konvertierbar ist. Vielleicht funktioniert ja
folgender Ansatz, ansonsten kann man das ganze sicher mit Typelisten
lösen und wahrscheinlich hat boost da auch schon etwas parat.
struct kein_double{ char m[1000];};
struct ein_double{};
kein_double test(...) { return kein_double();}
ein_double test(double) { return ein_double();}
template <bool>
struct foo
{
template <class T>
static void mache(const T&);
};
template <>
struct foo<true>
{
static void mache(double);
};
template <class T>
void mache(const T& t)
{
foo<sizeof(test(t)) == sizeof(ein_double)>::mache(t);
}
mfg Torsten
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Falk Tannhäuser Guest
|
Posted: Fri Oct 29, 2004 9:20 pm Post subject: Re: Statische Polymorphie |
|
|
Torsten Robitzki wrote:
| Quote: | struct kein_double{ char m[1000];};
struct ein_double{};
kein_double test(...) { return kein_double();}
ein_double test(double) { return ein_double();}
[...]
template <class T
void mache(const T& t)
{
foo
}
|
boost::is_convertible macht's wohl so ähnlich und
könnte hier sicher auch genommen werden.
Ansonsten könnte man das Ursprungsproblem eventuell auch
umgekehrt lösen, indem man per SFINAE (Google weiß, was
das ist ) auf das Vorhandensein der Memberfunktion
'double getx() const' testet und danach das Hilfstemplate
'foo' spezialisiert.
template<typename T, typename FuncPtr, FuncPtr fp> struct wrap_func_ptr;
template<typename T>
char has_member_getx_helper(T const&, wrap_func_ptr<T, double (T::*)() const, &T::getx>* = 0);
char ( &has_member_getx_helper(...) )[2];
#define has_member_getx(t) (sizeof has_member_getx_helper(t) == sizeof(char))
Zu beachtende Einschränkungen:
- Die Signatur muss genau stimmen (es reicht z.B. nicht, nur einen nach 'double'
konvertierbaren Rückgabetyp wie 'int' zu haben),
- Ererbte Funktionen werden nicht gefunden,
- Die Funktion muss 'public' sein, sonst Compilerfehler
- Der Compiler sollte auf dem neusten Stand sein, was die Normkonformität angeht
(g++/Cygwin Version 3.3.3 schluckt's nicht, mit der 3.4.1 geht's).
Ob sich die ersten beiden Punkte mit etwas (oder viel) mehr Aufwand beheben lassen,
wüsste ich jetzt auf die Schnelle nicht zu sagen (mit Hife von boost::is_convertible
bzw. boost::is_base_and_derived o.ä.?).
MfG
Falk
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Markus Breuer Guest
|
Posted: Mon Nov 01, 2004 7:44 am Post subject: Re: Statische Polymorphie |
|
|
Boris wrote:
| Quote: | Hallo,
ich möchte gerne statische Polymorphie nutzen, da zur Laufzeit klar
ist, welche Klasse benutzt wird. Ich habe also 4 Klassen (A, B, C, D)
welche eine Methode
double getx();
haben. Nun habe ich eine Funktion "mache"
template <typename T
void mache (const T& t){
....
x = t.getx();
}
Diese Funktion habe ich aber auch für den Typ double
void mache (const double& t){
....
x = t;
}
Wenn ich nun folgenden Aufruf mache, gibt der Compiler einen Fehler:
mache (1); //Error
mache (1.1); //OK
Der Grund ist mir klar, er findet keine Methode für int, benutzt also
die template Variante, int hat aber keine Methode getx() => Fehler.
Wie kann ich OHNE für jeden Typ eine Methode "mache" zu schreiben das
Problem lösen? Ich möchte aus Performacegründen auch keine virtuellen
Funktionen benutzen.
Über Lösungsideen bin ich dankbar,
Boris
|
Hallo Boris,
was pricht dagegen, die Lösung wie folgt zu definieren:
template<typename T>
void mache( const T& t )
{
x = t;
}
template<>
void mache( const A& t )
{
x = t.get();
}
template<>
void mache( const B& t )
{
x = t.get();
}
template<>
void mache( const C& t )
{
x = t.get();
}
template<>
void mache( const D& t )
{
x = t.get();
}
Gruß Markus
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Torsten Robitzki Guest
|
Posted: Thu Nov 04, 2004 4:09 pm Post subject: Re: Statische Polymorphie |
|
|
Markus Breuer wrote:
| Quote: | Boris wrote:
Hallo,
ich möchte gerne statische Polymorphie nutzen, da zur Laufzeit klar
ist, welche Klasse benutzt wird. Ich habe also 4 Klassen (A, B, C, D)
welche eine Methode
double getx();
haben. Nun habe ich eine Funktion "mache"
template <typename T> void mache (const T& t){
....
x = t.getx();
}
Diese Funktion habe ich aber auch für den Typ double
void mache (const double& t){
....
x = t;
}
Wenn ich nun folgenden Aufruf mache, gibt der Compiler einen Fehler:
mache (1); //Error
mache (1.1); //OK
Der Grund ist mir klar, er findet keine Methode für int, benutzt also
die template Variante, int hat aber keine Methode getx() => Fehler.
Wie kann ich OHNE für jeden Typ eine Methode "mache" zu schreiben das
Problem lösen? Ich möchte aus Performacegründen auch keine virtuellen
Funktionen benutzen.
Über Lösungsideen bin ich dankbar,
Boris
Hallo Boris,
was pricht dagegen, die Lösung wie folgt zu definieren:
|
Seit wann kann man Funktionstemplates spezialisieren? Für den Fall, das
A, B, C, und D konkrete Typen sein sollen, würde es Überladung tun.
| Quote: | template
void mache( const T& t )
{
x = t;
}
template
void mache( const A& t )
{
x = t.get();
}
snip |
mfg Torsten
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Markus Schaaf Guest
|
Posted: Thu Nov 04, 2004 4:56 pm Post subject: Re: Statische Polymorphie |
|
|
"Torsten Robitzki" <MyFirstname (AT) Robitzki (DOT) de> schrieb:
| Quote: | Seit wann kann man Funktionstemplates spezialisieren?
|
Seit es sie gibt.
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|