2013-10-04 15 views
5

Di seguito è riportato il codice per trovare e sostituire una stringa secondaria da una stringa.Ma non sono in grado di passare argomenti alla funzione.Errore nell'inizializzazione non valida del riferimento non costante di tipo

messaggio di errore:

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

prega di aiutare con spiegazione

#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

Non è possibile associare un temporaneo per un riferimento non-const. Cosa dovrebbe cambiare? – chris

+1

Il temporaneo, naturalmente. Non ho mai veramente accettato questa regola, ma una volta ho ricevuto una risposta dallo stesso Bjarne Stroustrup che diceva che sentiva di permettere al codice di modificare i provvisori come se fosse "troppo confuso". – john

risposta

5

Una spiegazione semplificata è che, poiché la funzione replaceAll sta cambiando una stringa, è necessario dare uno stringa effettiva di cambiare.

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

Trovo la tua "spiegazione semplificata" abbastanza semplice! – SimplyKnownAsG

1

Questo dovrebbe rimuovere l'errore:

#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

Questo è corretto. Tuttavia la vera domanda è perché il codice originale è un errore, piuttosto che fare esattamente ciò che fa. Ciò che questo codice fa è ciò che l'utente si aspetta (sarebbe più ovvio se replaceAll restituisse alcune altre informazioni come ad esempio quante sono state sostituite, in modo che abbia senso che il codice voglia ignorare la stringa modificata). – user3080602

1

Se si vuole essere in grado di passare provvisori come parametro, si potrebbe restituire il risultato, invece:

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

problema con il tuo codice è che stai provando a fare riferimento a un oggetto temporaneo usando un riferimento non costante.Compiler crea oggetti temporanei per la valutazione dell'espressione per memorizzare temporaneamente il valore dell'oggetto (per parametro pas cantare, restituire valori da una funzione, ecc.) È possibile assegnare l'indirizzo di un oggetto non costante a un puntatore const perché si sta semplicemente promettendo di non modificare qualcosa che è ok cambiare. Ma non è possibile assegnare l'indirizzo di un oggetto const a un riferimento non const perché questo consentirà di modificare l'oggetto in un secondo momento. modo corretto sarà quello di utilizzare una variabile temporanea per passare il parametro

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

come @Umer e @ John Ha scritto

+2

Questa è una spiegazione un po 'fuorviante. Il problema non è che la stringa tra virgolette sia costante, il problema è in realtà che le stringhe tra virgolette non sono di tipo std :: string, quindi il compilatore deve costruire un * temporaneo * std :: string per chiamare il funzione, e la regola in C++ non è possibile associare un riferimento non const a un temporaneo. La stessa regola fermerebbe questo codice compilando 'string function_returning_a_string(); ... replaceAll (function_returning_a_string(), "n", "k"); 'anche se in questo caso non è coinvolto alcun const. – john

+0

Thnx @john fr elaborando :) – maximus

+0

Purtroppo i provvisori non sono costanti. Ad esempio questo codice è legale 'string function_returning_a_string(); ... function_returning_a_string() = "abc"; '. La regola è che non è possibile associare un riferimento non const a un temporaneo, indipendentemente dal fatto che il temporaneo sia costante o meno irrilevante. Se rimuovi '(che è una costante)' allora è OK. – john

Problemi correlati