Zeiger auf Template-Funktion
-
Hallo,
der Code und die Überschrift sagen schon aus, was ich machen will. Nämlich die Funktion "func1" über den Zeiger "func_ptr" ansprechen. Prinzipiell ist das auch kein Problem, sobald aber Templates ins Spiel kommen, weiß ich mir nicht mehr zu helfen. Kann mir einer die Lösung verraten?

template<class A> A func1(A x) {return x;} template<class A> A (*func_ptr)(A); int main() { func_ptr = &func1; (*func_ptr)(2); }Danke,
~moagnus
-
Ich befürchte mit templates wird das so nicht gehen.
Eigentlich interpretiere ich ein template ehr als eine Art Macro.Ein template wird für jede übergebene Klasse neu expantierd und compiliert.
Das Problem ist dann folglich das es mehrere func1 Funktionen in deinem Programm geben kann und der Pointer demzufolge nicht wissen kann was dann gemeint ist.
Obs da eine Lösung gibt weiß ich nicht, aber wenn es da eine Chance geben soll dann müste die übergebene Klasse mit rein.
Vielleicht irgendwie über ein typedef.
Babbage
-
Hi,
Dein Problem ist, dass es nur Klassen- und Funktionstemplates gibt. Was Du aber möchtest, ist ein "Objekttemplate", denn dies hier:
moagnus schrieb:
...
A (*func_ptr)(A);soll ja weder eine Klasse noch eine Funktion, sondern ein konkretes Objekt (hier vom Typ "Funktion mit Parameter- und ReturnTyp A") anlegen.
Mein Vorschlag: Mach eine Klasse draus:
template <typename A> struct MyFunc { static A (*func_ptr)(A); }; int main() { MyFunc<A>::func_ptr = &func1; (*MyFunc<A>::func_ptr)(2); }Das müsste gehen (kann es aber gerade nicht ausprobieren.
Gruß,
Simon2.
-
Hm, jetzt werden halt mehrere Klassen für verschiedene Datentypen angelegt. Das machts leider auch nicht eindeutiger.
-
Hallo moagnus,
entweder du mußt dir in der Funktion bereits über dem Typ im Klaren sein
(was du wegen deiner Parameter-Angabe scheinbar bist):#include <iostream> template<class A> A func1(A x) {return x;} int main() { typedef int (*func_ptr)(int); func_ptr ptr = &func1; std::cout << ptr(2) << std::endl; return 0; }oder deine Funktion muss wiederum eine Template-Funktion sein und den Parameter
woanders her kriegen:#include <iostream> template<class A> A func1(A x) {return x;} template<class A> void print(A a) { typedef A (*func_ptr)(A); func_ptr ptr = &func1; std::cout << ptr(a) << std::endl; }; int main() { print<int>(2); print<char>('c'); return 0; }Diese beiden Möglichkeiten, kann ich dir vorschlagen.
Falls du noch was anderes brauchst, poste einfach nochmal.
Gruß,
CSpille
-
moagnus schrieb:
Hm, jetzt werden halt mehrere Klassen für verschiedene Datentypen angelegt. ...

Ich weiß nicht, was Du erwartest ... einen Zeiger, der typsicher auf alle Typen zeigen kann ?
Das wird so nicht klappen ... jedenfalls nicht mit templates, weil templates IMMER pro Typ instantiiert werden. Das bedeutet: Selbst wenn Dein ursprüngliches Konstrukt funktionierte, würde es ebenfalls "... mehrere [Zeiger] für verschiedene Datentypen ..." anlegen.Entweder lebst Du also mit der "Vielfältigkeit" (denn es ist zwar "vielfältig" aber durchaus "eindeutig", sonst bekäme der Compiler das auch nicht hin) oder Du verabschiedest Dich von der Typsicherheit und hantierst mit void*-Funktionspointern herum, die Du bei Bedarf castest. Letztlich wirst Du aber auch hier nicht darum herumkommen, weil Du spätestens beim Zugriff selbst qualifizieren musst (C++ besteht nunmal darauf, nicht auf void zugreifen zu können) .... und da hast Du wieder eine "Instanz" pro Typ.
Gruß,
Simon2.
-
Die zweite Lösung von CSpille gefällt mir ganz gut. Auf das Gecaste verzichte ich jetzt mal, zumal mein Problem eher hypothetisch war.
Danke für eure Antworten.
