2013-10-04 6 views
5

Unten ist der Code zum Suchen und Ersetzen einer Teilzeichenfolge aus einer Zeichenfolge. Ich bin jedoch nicht in der Lage, Argumente an die Funktion zu übergeben.Fehler in ungültiger Initialisierung der nichtkonstanten Referenz des Typs

Fehlermeldung:

invalid initialization of non-const reference of type ‘std::string& {aka std::basic_string&}’ from an rvalue of type ‘const char*’

bitte mit Erklärung helfen

#include <iostream> 
#include <string> 
using namespace std; 

void replaceAll(string &s, const string &search, const string &replace) { 
    for(size_t pos = 0; ; pos += replace.length()) { 
     pos = s.find(search, pos); 
     if(pos == string::npos) break; 
     s.erase(pos, search.length()); 
     s.insert(pos, replace); 
    } 
} 
int main() { 

    replaceAll("hellounny","n","k"); 
    return 0; 
} 
+1

Sie keine temporäre Bindung an eine nicht konstante Referenz kann passieren. Was soll es ändern? – chris

+1

Das temporäre natürlich. Ich habe dieser Regel nie wirklich zugestimmt, aber ich habe einmal eine Antwort von Bjarne Stroustrup selbst erhalten, in der er sagte, dass er fühlte, Code zuzulassen, um solche Provisorien wie "zu verwirrend" zu modifizieren. – john

Antwort

5

Eine vereinfachte Erklärung ist, dass da Ihre replaceAll Funktion eine Zeichenfolge ändert, können Sie es eine tatsächliche Zeichenfolge zu ändern, geben muss.

int main() { 
    string str = "hellounny"; 
    replaceAll(str,"n","k"); 
    return 0; 
} 
+0

Ich finde Ihre "vereinfachte Erklärung" ganz einfach! – SimplyKnownAsG

1

Dieser den Fehler beseitigen soll:

#include <iostream> 
#include <string> 
using namespace std; 

void replaceAll(string &s, const string &search, const string &replace) { 
    for(size_t pos = 0; ; pos += replace.length()) { 
     pos = s.find(search, pos); 
     if(pos == string::npos) break; 
     s.erase(pos, search.length()); 
     s.insert(pos, replace); 
    } 
} 
int main() { 

    string temp = "hellounny"; 
    replaceAll(temp,"n","k"); 
    return 0; 
} 
+1

Das ist richtig. Die eigentliche Frage ist jedoch, warum der ursprüngliche Code ein Fehler ist, anstatt genau das zu tun. Was dieser Code tut, ist, was der Benutzer erwartet (es wäre offensichtlicher, wenn replaceAll einige andere Informationen zurückliefert, wie zB wie viele ersetzt wurden, so dass es Sinn macht, dass der Code die modifizierte Zeichenkette ignorieren möchte). – user3080602

1

Wenn Sie als Parameter in Provisorien wollen in der Lage zu passieren, man konnte das Ergebnis zurück statt: mit

std::string replaceAll(string s, const string &search, const string &replace) { 
    for(size_t pos = 0; ; pos += replace.length()) { 
     pos = result.find(search, pos); 
     if(pos == string::npos) break; 
     result.erase(pos, search.length()); 
     s.insert(pos, replace); 
    } 
    return s; 
} 

std::string result = replaceAll("hellounny", "n", "k"); 
0

Problem Ihr Code ist, dass Sie versuchen, ein temporäres Objekt zu referenzieren, indem Sie einen nicht konstanten Verweis verwenden. Compiler erstellt temporäre Objekte für die Auswertung von Ausdruck, um den Objektwert vorübergehend zu speichern (für Parameter pas sing, Rückgabe von Werten aus einem func etc). Sie können einem konstanten Zeiger die Adresse eines nicht konstanten Objekts zuweisen, da Sie einfach versprechen, nichts zu ändern, das in Ordnung ist. Sie können die Adresse eines konstanten Objekts jedoch nicht einer nichtkonstanten Referenz zuweisen, da Sie das Objekt später ändern können. korrekte Art und Weise wird eine temporäre Variable verwenden, um den Parameter

int main() 
{ 
    string temp = "This is a Temperory Var"; 
    replaceAll(temp,"n","k"); 
} 

als @Umer und @John Schrieb

+2

Das ist eine etwas irreführende Erklärung. Das Problem ist nicht, dass die Zeichenkette in Anführungszeichen konstant ist, das Problem besteht darin, dass Zeichenketten in Anführungszeichen nicht vom Typ std :: string sind, also muss der Compiler eine * temporäre * std :: Zeichenkette konstruieren, um die Funktion, und die Regel in C++ ist, dass Sie eine nicht-konstante Referenz nicht an eine temporäre binden können. Die gleiche Regel würde diesen Code beim Kompilieren von 'string function_returning_a_string(); ... replaceAll (function_returning_a_string(), "n", "k"); 'obwohl in diesem Fall keine const involviert ist. – john

+0

Thnx @john fr Ausarbeitung :) – maximus

+0

Leider sind Provisorien nicht konstant. Zum Beispiel ist dieser Code legal 'string function_returning_a_string(); ... function_returning_a_string() = "abc"; '. Die Regel besteht darin, dass Sie eine nicht-konstante Referenz nicht an eine temporäre Bindung binden können, unabhängig davon, ob die temporäre Konstante konstant ist oder nicht. Wenn Sie '(das ist eine Konstante)' entfernen, ist es in Ordnung. – john

Verwandte Themen