Mittels std::string zu Funktion gelangen
-
Na ja, ne Möglichkeit wäre sowas:
#include <unordered_map> #include <iostream> #include <string> #include <stdexcept> class blubb { std::unordered_map<std::string, void (*) ()> functions_; public: template <typename R, typename... Args> R call(const std::string& name, Args... args) { auto found = functions_.find(name); if (found == functions_.end()) throw std::runtime_error("blubb"); return reinterpret_cast<R (*) (Args...)>(found->second)(args...); } template <typename F> void set(std::string name, F f) { functions_[std::move(name)] = reinterpret_cast<void (*) ()>(f); } }; double add(double a, double b) { return a + b; } int main() { blubb b; b.set("add", add); std::cout << "5 + 3 = " << b.call<double>("add", 5.0, 3.0) << '\n'; }Aber ehrlich gesagt.. super gefährlich und nicht gerade schön. Ich würde eher nach einer komplett anderen Lösung suchen, wenn unterschiedliche maps nicht in Frage kommen.
-
Danke schonmal für die Antworten.
Doch doch, unterschiedliche Maps kommen in Betracht(werds vermutlich auch so machen), aber würde gerne wissen ob es da bessere/andere Standardlösungen gibt.
-
Hmmm, ärgerlich an der std::map variante ist(so wie ich das sehe), das man, auch wenn nur eine vorhanden ist, funktionen mit von anderen abweichender parameterzahl in eine extra std::map packen muss, da sie einen eigenen funktionenzeigertypen benötigen

-
du könntest verschiedene structs als Parameter übergeben in denen dann die Parameter stecken
greetz KN4CK3R
-
Namenloser324 schrieb:
Heho, ich überlege mir gerade bzw. versuche herauszufinden, wie man es am besten löst eine Zuordnung und Aufrufung von std::string zu einer gewünschten Funktion zu erstellen.
Wozu denn eigentlich?
-
krümelkacker schrieb:
Namenloser324 schrieb:
Heho, ich überlege mir gerade bzw. versuche herauszufinden, wie man es am besten löst eine Zuordnung und Aufrufung von std::string zu einer gewünschten Funktion zu erstellen.
Wozu denn eigentlich?
parser von arithmetischen ausdrücken bei denen auch noch einige funktionen aufrufbar sein sollen
-
Schreib deine Funktionen als T(vector<T>), wobei T der Werttyp ist.
-
struct value_type { enum Enum { Integer, Float, Boolean, Nil, }; }; typedef value_type::Enum ValueType; typedef long long Integer; typedef double Float; typedef bool Boolean; struct Value { ValueType type; union { Integer i; Float f; Boolean b; }; Value(); Value(Integer i); Value(Float f); Value(Boolean b); }; Integer toInteger(const Value &value) { switch (value.type) { case value_type::Integer: return value.i; case value_type::Float: return static_cast<Integer>(value.f); case value_type::Boolean: return value.b; default: throw std::runtime_error("Not convertible to integer"); } } Float toFloat(const Value &value); typedef std::function<Value (const std::vector<Value> &)> Function; struct FunctionRegistry { void add(std::string name, Function function); Value call(const std::string &name, const std::vector<Value> &arguments) const; //impl sollte klar sein private: typedef std::map<std::string, Function> FunctionsByName; FunctionsByName m_functionsByName; }; static void expectArgumentCount(const std::vector<Value> &args, size_t count) { if (args.size() != count) { throw std::runtime_error("Wrong argument count"); } } int main() { FunctionRegistry reg; reg.add("sin", [](const std::vector<Value> &args) -> Value { expectArgumentCount(args, 1); return Value( static_cast<Float>(std::sin( toFloat(args[0])))); }); cout << toFloat(reg.call("sin", std::vector<Value>(1, Value(123)))) << endl; }
-
Kellerautomat schrieb:
Schreib deine Funktionen als T(vector<T>), wobei T der Werttyp ist.
Gute Idee, der vector ist natürlich elegant.
@TyRoXx
wow, vielen dank, muss mir das erstmal ne weile anschauen bis ich da durchsteige
sehr cool!
-
Ne Frage zum Code von dir TyRoxx:
was genau wird hier gemacht:
reg.add("sin", [](const std::vector<Value> &args) -> Value { expectArgumentCount(args, 1); return Value( static_cast<Float>(std::sin( toFloat(args[0])))); });ist da nicht aufruf der funktion mit definition verwechselt?!
und wieso gibt es dort die geschweifte klammer? wird das array initialisiert?!
-
Das ist kein Array, das ist eine Lambadafunktion von C++11. Genaue Syntax am besten selber googeln.
-
Jonas OSDever schrieb:
Das ist kein Array, das ist eine Lambadafunktion von C++11. Genaue Syntax am besten selber googeln.
Ah, gut zu wissen, damit habe ich noch gar nicht gearbeitet, danke.