Multimethoden in C++
-
Hallo Forum,
ich habe mich mal daran versucht Multimethoden in C++ zu simulieren. Hier ist mein bisheriger Fortschritt mit Kommentaren im Quellcode.template < typename TReturnType, typename TType > // momentan nur ein Parameter für die Multimethode class Dispatch { public: template < typename TFunction > void setDispatch(TFunction&& fn) noexcept // definiert die Funktion für dieses Dispatch { dispatch_ = fn; } decltype(auto) dispatch() { if (dispatch_ != nullptr) { return std::forward<std::function<TReturnType(TType)>>(dispatch_); // gibt eine rValue-Referenz der Funktion zurück } throw std::exception(""); // ruft std::terminate in operator() von class MultipleDispatch auf, wenn Funktion nicht definiert ist! } private: std::function<TReturnType(TType)> dispatch_; // Funktionwrapper, der auf nullptr zeigt, solange er nicht explizit einem Ziel zugewiesen wird };template < typename TReturnType, typename... TTypes > // Die eigentliche "Multimethode" in Form eines Funktors class MultipleDispatch { public: template < typename TType, typename TFunction > void setDispatch(TFunction&& fn) noexcept { std::get<Dispatch<TReturnType, TType>>(dispatchTable_).setDispatch(std::forward<TFunction>(fn)); } template < typename TType > TReturnType operator()(TType value) noexcept // überladener () Operator, um der Syntax eines Funktionsaufrufes zu ähneln ( Funktor ) { return std::get<Dispatch<TReturnType, TType>>(dispatchTable_).dispatch()(value); } private: std::tuple<Dispatch<TReturnType, TTypes>...> dispatchTable_; // ein TUple das alle Variationen des Funktors enthält };// Beispiel zur Anwendung template < typename... TTypes > class Base { public: virtual ~Base() {} public: MultipleDispatch<void, TTypes...> foo; // Instanz des Funktors mit den gewünschten Typen }; class Derived : public Base<int, float> { public: Derived() { // Hier werden die einzelnen Variation der Funktion definiert, je nach Typ des Templateparameters foo.setDispatch<int>([this](int x) { std::cout << x << "\n"; }); // über this-Capture kann die Lambdafunktion auf die Member von Derived zugreifen ! foo.setDispatch<float>([this](float x) { std::cout << x * 2 << "\n"; }); } }; int main() { Base<int, float>* b = new Derived(); Derived d; b->foo(5); // 5 b->foo(5.f); // 10 d.foo(10); // 10 d.foo(10.f); // 20 /*d.foo(10.5);*/ // Compiletime error delete b; std::getchar(); return 0; }Wie findet ihr den Ansatz ? Mein nächstes Ziel ist es, Funktionen mit mehreren Parametern zu ermöglichen.
-
Irgendwie seh ich grad nicht, warum das jetzt Multimethoden sein sollten...
-
hm kanns sein, dass ich den falschen Begriff für mein Problem gegoogelt hab ?
