Datentyp zur Leufzeit festlegen
-
freak4fun schrieb:
Wie mache ich das?

Die Frage ist eher, was du hinterher damit vorhast.
-
freak4fun schrieb:
Moin,
ich möchte den Benutzer einen Datentyp festlegen lassen. Er soll von einer Auswahl (Combobox) vorgegebener Typen (String, int, double) wählen können. Wie mache ich das?
python nehmen
-
Im entferntesten kannst du so etwas mit Laufzeitpolymorphie erreichen. Sinvoller wird es dadurch aber auch nicht.
-
Müsste mit einer
union foo { std::string str; int i; double d; }oder wilder
reinterpret_cast<type>klappen, aber das beste wäre wohl das Design zu über denken.
-
Einfacher Vorschlag:
Packe alles, was der Benutzer machen soll in einzelne Funktionen, die sich nach dem Datentyp unterscheiden. Also FunctionInt, FunctionDouble, FunctionString, etc. Dann lasse - wie gewünscht - den Benutzer in der Combobox auswählen. Alternativ kannst du auch mit Funktionsüberlagerung auskommen - erscheint mir aber etwas aufwendiger.
-
irgendwer schrieb:
Müsste mit einer
union foo { std::string str; int i; double d; }Naja... Zu dem Design brauch man wohl nix sagen...
irgendwer schrieb:
oder wilder
reinterpret_cast<type>Ui...
wilder?
Allerdings...
Sag mir einen Compiler oder Betriebssystem, wo das funktioniert.
Das funktioniert weder von int nach double oder umgekehrt, geschweige denn mit std::stringEDIT: Funktioniert heißt nicht nur kompiliert

-
Naja. Man könnte das natürlich auch umgehen und das ganze mit Zeigern machen. Wird wegen dem aber nicht besser.
Besseres Design ist hier wahrscheinlich die beste Lösung.
-
drakon schrieb:
Besseres Design ist hier wahrscheinlich die beste Lösung.
Eine genauere Problemspezifikation wäre der erste Schritt

-
CSpille schrieb:
drakon schrieb:
Besseres Design ist hier wahrscheinlich die beste Lösung.
Eine genauere Problemspezifikation wäre der erste Schritt

Nein. Es macht keinen Sinn, dass er sein Problem beschreibt, wozu er offensichtlich den falschen Weg wählt. Wenn er nochmal über das Design nachdenkt, dann wird er wahrscheinlich selbst auf eine bessere Lösung kommen.
-
drakon schrieb:
Naja. Man könnte das natürlich auch umgehen und das ganze mit Zeigern machen. Wird wegen dem aber nicht besser.
War dieser Kommentar auf den reinterpreter_cast bezogen?
Dafür würde dann aber auch ein static_cast reichen:
#include <iostream> #include <string> int main(int argc, char** argv) { void* v; int i = 123; v = &i; std::cout << *static_cast<int*>(v) << std::endl; double d = 1.23; v = &d; std::cout << *static_cast<double*>(v) << std::endl; std::string s("1,23"); v = &s; std::cout << *static_cast<std::string*>(v) << std::endl; return 0; }
-
drakon schrieb:
CSpille schrieb:
drakon schrieb:
Besseres Design ist hier wahrscheinlich die beste Lösung.
Eine genauere Problemspezifikation wäre der erste Schritt

Nein. Es macht keinen Sinn, dass er sein Problem beschreibt, wozu er offensichtlich den falschen Weg wählt. Wenn er nochmal über das Design nachdenkt, dann wird er wahrscheinlich selbst auf eine bessere Lösung kommen.
Ich denke hier gibt es zwei verschiedene Ebenen der Problemspezifikation.
Eine für die Benutzeranforderungen und eine auf C++-Ebene.
Ich meinte dabei die Benutzeranforderungen.
-
CSpille schrieb:
Ich denke hier gibt es zwei verschiedene Ebenen der Problemspezifikation.
Eine für die Benutzeranforderungen und eine auf C++-Ebene.
Ich meinte dabei die Benutzeranforderungen.Sehe ich auch so. Imho ist es in den seltesten Fällen sinnvoll den Benutzer mit Typisierung zu quälen, es sei den das ist Teil der Problemstellung.
-
Einigen wir uns darauf, dass sowohl
union,reinterpret_castals auchstatic_castungeeignet (wenn nicht unmöglich) sind und warten, bis freak4fun sich genau ausdrückt?
-
Nexus schrieb:
Einigen wir uns darauf, dass sowohl
union,reinterpret_castals auchstatic_castungeeignet (wenn nicht unmöglich) sind und warten, bis freak4fun sich genau ausdrückt?Ja, das klingt gut.

Es geht um folgendes: Ich möchte csv-Dateien importieren deren Aufbau ich nicht kenne. Der Benutzer soll nun wählen können, ob es sich bei einer Spalte um eine Zeichenkette, eine Ganzzahl oder eine Kommazahl handelt.
Ja, ich traue diese Auswahl zu.
Ich bin prinzipiell für jede Idee dankbar. Gern auch eine Lösung um den benutzer die Entscheidung abzunehmen.

Ich find es riesig wie sehr ihr euch hier bemüht, vielen Danke!

-
da csv text ist und bleibt, würde ich das auch so belassen.
Einfach Eingabe/Ausgabe entsprechend "Filtern";int ValueType; std::string csvValue; switch(ValueType) { case 0: // Hier Int einlesen csvValue = // int to string break; case 1: // Hier float einlesen csvValue = // float to string break; case 3: // Hier string einlesen csvValue = // string break; }oder halt über laufzeit polymorphie
class Basis { public: virtual std::string GetValue() = 0; virtual void SetValue(std::string text) = 0; }; class IntKlasse : public Basis { int Value public: virtual std::string GetValue(); virtual void SetValue(std::string text); } class FloatKlasse : public Basis { float Value public: virtual std::string GetValue(); virtual void SetValue(std::string text); } usw..
-
freak4fun schrieb:
Es geht um folgendes: Ich möchte csv-Dateien importieren deren Aufbau ich nicht kenne.
Was willst du nach dem Importieren mit den Daten machen?
-
@BigNeal: Danke, das sieht sehr interessant aus. Das schau ich mir mal an.

@CSpille: Duchschnitte berechnen mit den Double/int, Strings zB als Anzeigenamen. Die CSV-Dateien werden dann als eine Datei zusammengefasst.

-
@ BigNeal:
#include <string> #include <sstream> #include <iostream> class Type { protected: std::stringstream myStream; public: std::string getValue() const { return myStream.str(); } }; class TypeString : public Type { public: TypeString(const std::string& s) { myStream << s; } }; class TypeInt : public Type { public: TypeInt(int i) { myStream << i; } }; class TypeFloat : public Type { public: TypeFloat(float f) { myStream << f; } }; int main() { TypeInt i(10); TypeFloat f(10.5); TypeString s("Test"); std::cout << i.getValue() << std::endl; std::cout << f.getValue() << std::endl; std::cout << s.getValue() << std::endl; }Aber wo soll der Sinn sein? Mit einem std::string kann man nicht rechnen!
-
Jetzt hab ich etwas zusammengefrickelt bekommen

#include <string> #include <sstream> #include <iostream> #include <ctime> #define DECLARE_NEW_TYPE(RealType, TypeName) class TypeName : public Type { public: TypeName(RealType a) { myStream << a; myType = #TypeName; } }; class Type { protected: std::stringstream myStream; std::string myType; public: template <typename T> T getValue() { T tmp; myStream >> tmp; return tmp; } const std::string& getType() const { return myType; } }; DECLARE_NEW_TYPE(int, TypeInt) DECLARE_NEW_TYPE(float, TypeFloat) DECLARE_NEW_TYPE(std::string, TypeString) int main() { TypeInt i(10); TypeFloat f(10.5); TypeString s("lol"); std::cout << i.getValue<int>() << ", " << i.getType() << std::endl; std::cout << f.getValue<float>() << ", " << f.getType() << std::endl; std::cout << s.getValue<std::string>() << ", " << s.getType() << std::endl; }Lässt sich leicht erweitern und der Typ kann auch mit getType zur Laufzeit ermittelt werden. und mit getValue<Typ> abgefragt werden.
-
Oha, das kann ja was werden. Da werd ich mich dan mal am WE ran setzen. Danke dir für deine Mühe, jkljkl ( sehr kreativer nick ^^).
