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.