string to std::any<any type>



  • Hallo Leute,

    Vieleicht könnt ihr mir helfen oder habt einen Rat für mich.

    Ich habe eine classe in der jeder beliebige Typ mit hilfe von any gespeichert
    werden kann.
    Ich möchte diese variablen reinitialisieren oder neu setzen über ein file
    welches geladen wird.

    Ich dachte schon über literale.
    Es wäre möglich den Typ in dem file zu speichern ala, "u","ll","b",etc..

    Leider fällt mir nichts ein wie ich das realisieren könnte.

    Könnte mir jemand bitte einen Denkanstoß geben?

    Hier ein simpler code, um zu zeigen was es können soll.

    Danke!

    #include <iostream>
    #include <experimental/any>
    #include <string>
    #include <vector>
    
    class cValue {
    public:
    	cValue(auto value) {
    		anyVar = value;
    	}
    
    	void setValue(std::string value) {
    		/* convert string anyhow into any type */
    		// anyVar = newTypevalue;
    	}
    
    	std::string getValue() {
    		std::string value = "";
    		/* convert any type anyhow into string */
    		// value = std::experimental::fundamentals_v1::any_cast<???>(anyVar);
    		return value;
    	}
    private:
    	std::experimental::fundamentals_v1::any anyVar;
    };
    
    int main() {	
    	std::string s = "";
    
    	cValue myLongValue(1L);
    	cValue myBoolValue(true);
    
    	std::cin >> s;
    	/* read new value and overwrite long value */
    	myLongValue.setValue(s);
    
    	std::cin >> s;
    	/* read new value and overwrite bool value */
    	myBoolValue.setValue(s);
    
    	/* need to be stored in a vector */
    	std::vector<cValue*> v;
    	v.push_back(&myLongValue);
    	v.push_back(&myBoolValue);
    
    	/* get string values from list */
    	for(const auto& value : v) {
    		std::cout << value->getValue() << std::endl;
    	}
    
    	return 0;
    }
    


  • Es ist schwer, dir zu helfen, weil wir nicht wissen, was genau du eigentlich mit deiner Klasse vorhast.

    Wenn du einen bestimmten Wert aus einem File auslesen willst, dann lies es aus (siehe hier) und übergebe den geparsten Wert deiner setValue() -Methode.
    Oder - halt je nach Kontext - gleich einen Operator für die Klasse definieren.



  • Danke für die zahlreiche Unterstützung.
    Ich habe eine Lösung für mich gefunden.
    Allerdings mit ein paar Hässlichkeiten.
    Wer es kompiliert wird es schon sehen.

    Falls jemand eine schönere Lösung hat, wäre ich sehr Dankbar darüber.

    #include <iostream>
    #include <experimental/any>
    #include <string>
    #include <vector>
    
    class cValue {
    public:
    	cValue(auto value) {
    		anyVar = value;
    	}
    
    	void setValue(const std::string& value, const std::string& type) {
    		if (type == "l") {
    			anyVar = std::stol(value);
    		} else if (type == "b") {
    			anyVar = value != "0";
    		} else if (type == "s")	{
    			anyVar = value;
    		} else {
    			std::cout << "got unknow type\n";
    		}
    	}
    
    	std::string getValue() {
    		std::string type = anyVar.type().name();
    		std::string value = "";
    
    		std::cout << "type: " << type << '\n';
    
    		if (type == "l") {
    			auto tmp = std::experimental::fundamentals_v1::any_cast<long>(anyVar);
    			value = std::to_string(tmp);
    		} else if (type == "b") {
    			auto tmp = std::experimental::fundamentals_v1::any_cast<bool>(anyVar);
    			value = std::to_string(tmp);
    		} else if (type == "s") {
    			value = std::experimental::fundamentals_v1::any_cast<std::string>(anyVar);
    		} else {
    			std::cout << "anyVar has unknown type\n";
    		}
    
    		return value;
    	}
    private:
    	std::experimental::fundamentals_v1::any anyVar;
    };
    
    void getInput(std::string& value, std::string& type) {
    	std::cin >> value;
    	std::cin >> type;
    }
    
    int main() {	
    	std::string value = "";
    	std::string type = "";
    
    	cValue myLongValue(1L);
    	cValue myBoolValue(true);
    	cValue myStringValue(std::string("empty"));
    
    	getInput(value, type);
    	/* read new value and overwrite long value */
    	myLongValue.setValue(value, type);
    
    	getInput(value, type);
    	/* read new value and overwrite bool value */
    	myBoolValue.setValue(value, type);
    
    	getInput(value, type);
    	/* read new value and overwrite string value */
    	myStringValue.setValue(value, type);
    
    	/* need to be stored in a vector */
    	std::vector<cValue*> v;
    	v.push_back(&myLongValue);
    	v.push_back(&myBoolValue);
    	v.push_back(&myStringValue);
    
    	/* get string values from list */
    	for(const auto& value : v) {
    		std::cout << value->getValue() << std::endl;
    	}
    
    	return 0;
    }
    


  • _lex schrieb:

    Falls jemand eine schönere Lösung hat, wäre ich sehr Dankbar darüber.

    Da an der Schnittstelle der Klasse - also setValue und getValue - sowieso nur ein std::string vorliegt, solltest Du diesen auch als Member halten und auf das ganze any-Kram verzichten. Einzig der Konstruktor wäre zu überarbeiten:

    class cValue {
    public:
        template< typename T >
        cValue(T value)
            : anyVar( std::to_string( value ) ) 
        {}
    
        void setValue(std::string value) {
            anyVar = value;
        }
    
        std::string getValue() const {
            return anyVar;
        }
    private:
        std::string anyVar;
    };
    

Anmelden zum Antworten