Der Typ des Typs eines Typs :)



  • Moin,

    hat der Typ eines Typs einen Typ insoweit, dass möglich ist:

    void foo(Type t, void* bar)
    {
      irgendein_cast<t>(bar);
    }
    

    Und da ich jetzt schon ahne, dass so etwas nicht geht: Kann man so ein Verhalten irgendwie immitieren, außer eine eigene Liste mit Typen zu führen?



  • decltype



  • Nein, ein Typ ist in C++ keine Variable und hat deshalb keinen eigenen Typ. Das nächste zu deinem Ansatz wären Templates:

    template<typename T>
    void foo(void* bar)
    {
      irgendein_cast<T*>(bar);
      ...
    }
    

    oder noch besser:

    template<typename T>
    void foo(const T& bar)
    {
      ...
    }
    


  • @cooky451:
    Sag einfach was du konkret machen willst.
    Es gibt verschiedene Dinge die man in C++ machen kann. Hier alles der Reihe nach aufzuzählen, nur damit du dann immer "ne, das meinte ich nicht" sagst, ist zu mühsam.



  • CStoll schrieb:

    Nein, ein Typ ist in C++ keine Variable und hat deshalb keinen eigenen Typ.

    Warum habe ich das geahnt? 🙂

    CStoll schrieb:

    Das nächste zu deinem Ansatz wären Templates:

    Ist leider nicht möglich. Ich kann ja mal den Hintergrund darlegen, was ich eigentlich vermeiden wollte..

    Ich möchte verschiedenen Funktionen, die alle die gleiche Signatur haben, im Prinzip unterschiedliche Parameter übergeben. Meine erste Überlegung war:

    void foo(std::vector<std::pair<std::type(?), void*>>);
    

    Doch das scheint ja jetzt gegessen zu sein. Da die Funktionen selbst den Typen kennen (jaja, ich weiß, alles super gefährlich, lasst mich halt basteln :p), wäre das nicht einmal ein Problem. Dann müsste ich aber auf new/delete verzichten und mit malloc/free arbeiten.

    Gibt es vielleicht eine ganz andere Lösung als meine? Einen Container der verschiedene Typen fassen kann? Denn noch mehr Gefrickel als das da geht kaum. 🙄

    Edit:

    hustbaer schrieb:

    Sag einfach was du konkret machen willst.

    LOL. Bitte sehr. 🙂



  • Sag noch konkreter, was Du machen willst.
    Hier bieten sich vielleicht virtuelle Funktionen an, vielleicht variadic templates, eventuell boost::any.



  • Willst du eine anständige Lösung? - Dann sag was du genau machen willst.
    Willst du nur ein zusammengebastel? - Dann mach was du willst.



  • Na, viel konkreter geht es nicht mehr. Ich habe eine rein virtuelle Basisklasse, die erbenden Klassen sollen alle über eine bestimmte Funktion aufgerufen werden, allerdings mit dynamisch vielen Parametern unterschiedlichen Typs.

    Edit:
    Vielleicht noch konkreter: Ich will Funktionen dynamisch zur Laufzeit aufrufen. (Und deren Parameter direkt bestimmen.)



  • Du erklärst, WIE du etwas machen willst, aber nicht WAS.



  • Sehe das auch so, wie "immer_noch_nicht"

    Aber wenn du das unbedingt machen willst, dann übergib einfach einen Container mit Schlüssel, Wert paaren. Der Schlüssel ist dann sozusagen der Namen der Variable (wenn da nichts ist, wurde es nicht übergeben) und den Wert kannst du dann so casten, wie es die Funktion braucht (wobei auch das dann fehl schlagen kann).



  • immer_noch_nicht schrieb:

    Du erklärst, WIE du etwas machen willst, aber nicht WAS.

    Ich gebe ein: "funktion(5, "hallo!")" und die Funktion "funktion" wird mit entsprechenden Parametern aufgerufen.

    drakon schrieb:

    Schlüssel, Wert

    Ich muss ja wissen von welchem Typ Wert ist. Momentan erzeuge ich die Parameter mit new, allerdings ist das Löschen von void*'s mit delete eher nicht so toll.

    Wie gesagt, wenn da jemand einen ganz anderen Ansatz hat, immer her damit! 🙂



  • cooky451 schrieb:

    Ich gebe ein: "funktion(5, "hallo!")" und die Funktion "funktion" wird mit entsprechenden Parametern aufgerufen.

    Jetzt haben wir's.
    Ist die Typsicherheit von C++ gewünscht, also daß Du direkt einen Fehler bekommst, wenn es keine passende Funktion gibt?
    Oder soll die Funktion ein beliebiges Parameter-Array nehmen und selber schauen, also ohne Überladung und Prototypenprüfung?
    Willst DU die Eingabe an echte C++-Funktionen wie die

    void funktion(int,char*);
    

    weiterleiten, oder baust Du die Funktionen, die so aufgerufen werden sollen erst noch?
    Sollen nur so ein paar Funktionen eingebbar sein, wie in einer Konsole in einem Game? Oder soll mehr rauskommen wie eine kleine Scripting-Sprache?



  • Dann ist halt der Wert eine Struktur mit einer id für den Typen und einem Wert, den du casten kannst.

    Ich bezweifle allerdings immer noch, dass du das so wirklich brauchst. Was soll denn die Funktion machen? Willst du ein printf nachbauen oder wie?



  • Du willst Reflection. Du willst die Erstellung dynamischer Variablen. Das geht in C++ nicht ohne Hardcoden oder einer Menge Makros oder beidem.

    D.h. du nimmst z.B. eine std::unordered_map<std::string, std::vector<std::unique_ptr<AbstractFunctionBase> > > oder so etwas und speicherst dann alle Funktionen darin. Den Rest mit den Parametern musst du dir ebenfalls irgendwie zusammentricksen. Viel Spaß.

    P.S.: Hat die Funktion "funktion" in deinem Beispiel garantiert die Parameter int, std::string? Kann sie überladen sein?



  • volkard schrieb:

    Ist die Typsicherheit von C++ gewünscht, also daß Du direkt einen Fehler bekommst, wenn es keine passende Funktion gibt?

    Das wäre gar nicht schlecht, allerdings denke ich nicht, dass das so wie ich mir das gerade vorstelle funktioniert.
    Kleine Scriptsprache trifft es eigentlich ganz gut. Ich möchte einer Klasse die Funktionen x, y, z, ..., bekannt machen und dann von außen auf diese zugreifen können.

    Edit:
    Templates und Überladungen sind nicht nötig. Nur simple Funktionen. 🙂



  • cooky451 schrieb:

    volkard schrieb:

    Ist die Typsicherheit von C++ gewünscht, also daß Du direkt einen Fehler bekommst, wenn es keine passende Funktion gibt?

    Das wäre gar nicht schlecht, allerdings denke ich nicht, dass das so wie ich mir das gerade vorstelle funktioniert.
    Kleine Scriptsprache trifft es eigentlich ganz gut. Ich möchte einer Klasse die Funktionen x, y, z, ..., bekannt machen und dann von außen auf diese zugreifen können.

    Wenns nicht so viel ist, einfach sehr simpel hardcoden (noch direkter als in meinem Beispiel). Wenn es mehr ist, würde sich evtl. ein selbst geschriebener Parser/Interpreter oder eine andere Programmiersprache eignen.



  • Würden Lua oder boost::python oder AngelScript *ALLE* Deine Träume erfüllen, aber zu Kosten von ein wenig Einarbeitungsaufwand?
    Oder sind die schief zu Deinem Problem?



  • wxSkip schrieb:

    Wenns nicht so viel ist, einfach sehr simpel hardcoden (noch direkter als in meinem Beispiel).

    Ne, das ist eigentlich nicht das, was ich erreichen möchte.

    volkard schrieb:

    Oder sind die schief zu Deinem Problem?

    Ziemlich, denn genau das hier ist mein Problem, da steckt (noch?) kein tieferer Sinn dahinter. Ich wollte nur mal ausprobieren, wie man so etwas schreiben könnte und jetzt habe ich mich hoffnungslos darin verbissen. 🙂



  • cooky451 schrieb:

    kein tieferer Sinn dahinter. Ich wollte nur mal ausprobieren, wie man so etwas schreiben könnte und jetzt habe ich mich hoffnungslos darin verbissen. 🙂

    Wenn Du selber machen wollst, fanch mit einem mathematischen Parser an.
    Am besten recursive descent.
    Der erstellt einen Baum, wo die Knoten Ausdrücke sind.
    Den kannste dann erweitern, daß die Knoten Kommandos, Definitionen, Deklarationen sind.
    Das macht viel Spaß.



  • cooky451 schrieb:

    volkard schrieb:

    Oder sind die schief zu Deinem Problem?

    Ziemlich, denn genau das hier ist mein Problem, da steckt (noch?) kein tieferer Sinn dahinter. Ich wollte nur mal ausprobieren, wie man so etwas schreiben könnte und jetzt habe ich mich hoffnungslos darin verbissen. 🙂

    Mein Tipp: Lass es. Mir kommen auch manchmal solche Ideen. Eine Any-Klasse ohne typeid() war gerade noch umzusetzen, aber sobald man mit Träumereien von beliebigen Programmen, die ihren Status jederzeit abspeichern und sich beim nächsten Programmstart genau an der selben Stelle mit den gleichen Daten wieder fortsetzen können, anfängt, sollte man besser aufhören. Es sei denn, man wird für diese "Visionen" bezahlt. 😃


Anmelden zum Antworten