Betrachten Sie das folgende, minimal Beispiel:Typ Löschung und eine Art Template-Methode Muster
struct S {
using func_t = void(*)(void *);
template<typename T>
static void proto(void *ptr) {
static_cast<T*>(ptr)->f();
}
func_t func;
void *ptr;
};
struct T {
void f() {}
};
void g(S &s) {
s.func(s.ptr);
}
int main() {
T t;
S s;
s.func = &S::proto<T>;
s.ptr = &t;
g(s);
}
Die ziemlich offensichtlich Idee ist es, die Art eines Bündels von Objekten zu löschen (wie T
, das ist nicht die einzige type), um ein Array von Instanzen von S
zu erstellen, dann über dieses Array zu iterieren und eine vorbestimmte Elementfunktion aufzurufen.
So weit so gut, es ist einfach zu implementieren und es funktioniert.
Nun würde Ich mag eine externe Funktion zur Verfügung zu stellen auf dem gelöschten Objekt aufgerufen werden, etwas, das so sein würde:
template<typename T, typename F>
static void proto(void *ptr, F &&f) {
auto *t = static_cast<T*>(ptr);
std::forward<F>(f)(*t);
t->f();
}
Oder diese:
template<typename T>
static void proto(void *ptr, void(*f)(T &)) {
auto *t = static_cast<T*>(ptr);
f(*t);
t->f();
}
als aufgerufen werden:
Eine Art Mustervorlagenmuster, bei dem die zusätzlichen Funktionen vom Aufrufer anstelle einer abgeleiteten Klasse bereitgestellt werden.
Leider kann ich das nicht tun, weil ich die Spezialisierungen nicht auf etwas Homogenes reduzieren kann, um einem Funktionszeiger zugewiesen zu werden.
Die einzige Alternative, die ich sehen kann, ist eine benutzerdefinierte Klasse wie die folgenden zu definieren:
struct C {
template<typename T>
void f(T &t) { /* ... */ }
// ...
};
Wo f
Versendungen irgendwie den Anruf intern auf die rechte Seite Funktion, dann verwenden Sie es als:
struct S {
using func_t = void(*)(void *, C &);
template<typename T>
static void proto(void *ptr, C &c) {
auto t = static_cast<T*>(ptr);
c.f(*t);
t->f();
}
func_t func;
void *ptr;
};
Das ist nicht weit von dem, was ich mit einem Lambda tun würde, aber es ist ausführlicher und erfordert, dass ich explizit die Klasse C
deklariere.
Gibt es noch eine andere gültige Alternative, um dasselbe zu erreichen, oder ist dies die einzige praktikable Lösung?
Ich fühle ein [XY-Problem] (https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Kannst du uns den Code geben, den du schreiben würdest, wenn du davon ausgibst, dass alle unterstützenden Template-Zauber perfekt funktionieren? – nwp
@nwp Ich gab etwas ähnliches. Stellen Sie sich vor, Sie hätten (würde ich sagen) ein gelöschtes Array, ich würde gerne darüber iterieren, indem ich 's.func (s.ptr, [] (auto obj) {/ * ... * /}); Zeit mit etwas anderen Lambdas. Kann ich Ihnen mehr Details geben? Ich bin mir nicht sicher, wie ich es besser erklären soll. Es tut mir Leid. – skypjack
Was ist das Gemeinsame aller Elemente im Array? Haben sie nur eine gemeinsame Mitgliedsfunktion 'void f()'? – nwp