Iterieren über eine std::map voll von strings in C++
Ich habe Folgendes Problem mit der Iteration über ein assoziatives array von strings definiert mit std::map
.
-- snip --
class something
{
//...
private:
std::map<std::string, std::string> table;
//...
}
In den Konstruktor, die ich füllen Sie die Tabelle mit Paaren von string-Schlüssel für string-Daten. Irgendwo anders habe ich eine Methode toString
zurückgibt, die ein string-Objekt, das enthält alle Schlüssel und die zugehörigen Daten in der Tabelle enthalten Objekt(key=Datenformat).
std::string something::toString()
{
std::map<std::string, std::string>::iterator iter;
std::string* strToReturn = new std::string("");
for (iter = table.begin(); iter != table.end(); iter++) {
strToReturn->append(iter->first());
strToReturn->append('=');
strToRetunr->append(iter->second());
//....
}
//...
}
Wenn ich versuche zu kompilieren bekomme ich folgende Fehlermeldung:
error: "error: no match for call to ‘(std::basic_string<char,
std::char_traits<char>, std::allocator<char> >) ()’".
Könnte jemand mir erklären, was fehlt, was mache ich falsch?
Ich fand nur einige Diskussion über ein ähnliches Problem in dem Fall von hash_map
wo der Anwender eine Hash-Funktion nutzen zu können hash_map
mit std::string
Objekte. Könnte etwas ähnliches auch in meinem Fall?
- Herzlich willkommen auf stack overflow, Crazybyte. Froh, dass ich helfen konnte
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ihr Hauptproblem ist, dass Sie den Aufruf einer Methode namens
first()
im iterator. Was Sie gemeint sind, zu tun ist, verwenden Sie die Eigenschaft namensfirst
:Als eine Frage des Stils, Sie shouldn ' T be using
new
zu erstellen, dass string.edit: facildelembrar hingewiesen (in den Kommentaren), dass in der modernen C++ - Sie können jetzt schreiben die Schleife
for(auto& item : table) {...}
Nicht schreiben
toString()
Methode. Dies ist nicht Java. Implementierung der stream-operator für die Klasse.Lieber mit den standard-algorithmen über das schreiben Ihrer eigenen Schleife. In dieser situation
std::for_each()
bietet ein nettes interface, was Sie tun möchten.Wenn Sie müssen eine Schleife verwenden, aber nicht wollen, um die Daten zu ändern, lieber
const_iterator
überiterator
. Auf diese Weise, wenn Sie versehentlich versuchen, und ändern Sie die Werte der compiler warnt Sie.Dann:
Dann, wenn Sie wollen, es zu drucken, nur stream-Objekt:
Wenn Sie wirklich brauchen eine string-Darstellung des Objekts, die Sie dann verwenden können
lexical_cast
.Den details, die noch ausgefüllt werden müssen.
operator<<()
Funktion fehlt ein&
auf den zurück geben?Ändern Sie den append-Aufrufe zu sagen
und
Zusätzlich die Linie
teilt einen string auf dem heap. Wenn Sie beabsichtigen, tatsächlich gibt einen Zeiger auf den dynamisch zugewiesenen string, der Rückkehr sollte geändert werden, um std::string*.
Alternativ, wenn Sie nicht wollen, zu kümmern, verwalten das Objekt auf dem heap, ändern Sie die lokale Deklaration
und ändern Sie die "append" fordert die Verwendung der Referenz-syntax...
statt
Bewusst sein, dass dies Konstrukt der string auf den stack, dann kopieren es an die return-variable. Dies hat Auswirkungen auf die Leistung.
Beachten Sie, dass das Ergebnis der Dereferenzierung eine std::map::iterator ist ein std::pair. Die Werte der
first
undsecond
sind keine Funktionen, Sie sind Variablen.Ändern:
zu
Dito mit
iter->second
.iter->first
unditer->second
sind Variablen, die Sie versuchen, Sie zu nennen als Methoden.Verwenden:
statt:
in c++11 können Sie
for ( auto iter : table ) { KeyType &key=iter.first; ValueType &value=iter.second; }
Anderen würdigen Optimierung ist die c_str ( ) Mitglied des STL string Klassen, das gibt eine unveränderliche null endende Zeichenfolge, die übergeben werden können, um als LPCTSTR, e. g., um eine benutzerdefinierte Funktion, die erwartet, dass ein LPCTSTR. Obwohl ich noch nicht verfolgt durch den Destruktor, um es zu bestätigen, ich vermute, dass die string-Klasse sieht nach der Erinnerung, in der es entsteht die Kopie.