return const_iterator reference?



  • Hallo,

    ich habe eine kleine Config Klasse welche meine Configdatei verarbeitet. Ich speicher sehr simpel in einer map die Schlüssel und Werte ab.

    // tstring ist std::wstring
    struct Pair {
    	tstring realKey;
    	tstring value;
    };
    std::unordered_map<tstring, Config::Pair> _map;
    
    		bool getBool(const tstring &key, bool defaultValue) const;
    		bool getBool(const tstring &key) const;
    		bool getBoolean(const tstring &key, bool defaultValue) const;
    		bool getBoolean(const tstring &key) const;
    
    		double getDouble(const tstring &key, double defaultValue) const;
    		double getDouble(const tstring &key) const;
    
    		float getFloat(const tstring &key, float defaultValue) const;
    		float getFloat(const tstring &key) const;
    
    		long getInt(const tstring &key, long defaultValue) const;
    		long getInt(const tstring &key) const;
    		long getInteger(const tstring &key, long defaultValue) const;
    		long getInteger(const tstring &key) const;
    
    		const tstring &get(const tstring &key, const tstring &defaultValue) const;
    		const tstring &get(const tstring &key) const;
    
    // Paar Beispiele der Funktionen (sind im Endeffekt eh fast alle gleich)
    	bool Config::getBool(const tstring &key, bool defaultValue) const
    	{
    		auto const &it = this->_map.find(key);
    		if (it == this->_map.end())
    		{
    			return defaultValue;
    		}
    
    		return (it->second.value.compare(_T("true")) == 0 || it->second.value.compare(_T("1")) == 0);
    		// return it->second.at(0) == '1';
    	}
    
    	bool Config::getBool(const tstring &key) const
    	{
    		return this->getBool(key, false);
    	}
    
    	// [[deprecated("getBoolean() ist nur eine alternative für getBool()")]]
    	bool Config::getBoolean(const tstring &key, bool defaultValue) const
    	{
    		return this->getBool(key, defaultValue);
    	}
    
    	// [[deprecated("getBoolean() ist nur eine alternative für getBool()")]]
    	bool Config::getBoolean(const tstring &key) const
    	{
    		return this->getBool(key, false);
    	}
    
    // Bei Int, Double kommen dann natürlich Typeumwandlung dazu
    

    Da ich jetzt aber gerne beim Schlüssel auf Groß- und Kleinschreibung verzichten möchte, dachte ich mir baue ich das ganze etwas um:

    std::unordered_map<tstring, Config::Pair>::const_iterator& Config::search(const tstring &key) const
    	{
    		tstring tmp = key;
    		std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower);
    		return this->_map.find(tmp);
    	}
    
    	bool Config::getBool(const tstring &key, bool defaultValue) const
    	{
    		// 
    		auto const &it = this->search(key);
    		if (it == this->_map.end())
    		{
    			return defaultValue;
    		}
    
    		// ...
    

    Leider wirft getBool dann einen Fehler. Lesezugriffsverletzung, was ich komisch finde, denn die _map existiert ja so lange die Klasse am leben ist, also der zurückgegebene iterator verliert seine Gültigkeit ja nicht nur weil er die search Funktion verlässt.



  • Du gibst aber keinen Iterator zurück, sondern eine Referenz auf einen temporären Iterator, der sofort danach zerstört wird.

    Zeile 5 darf gar nicht kompilieren, überprüfe mal deine Compilereinstellungen.


Log in to reply