2013-10-04 4 views
5

Ниже приведен код для поиска и замены подстроки из строки. Но я не могу передать аргументы функции.Ошибка при недействительной инициализации неконстантной ссылки типа

Сообщение об ошибке:

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

, пожалуйста, помогите с объяснением

#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

Вы не можете связать с временным неконстантной ссылкой. Что это должно измениться? – chris

+1

Временное, конечно. Я никогда не соглашался с этим правилом, но однажды получил ответ от самого Бьярна Страустрапа, который сказал, что он решил разрешить коду изменять временные ситуации, как это было «слишком запутанно». – john

ответ

5

Упрощенное объяснение состоит в том, что, так как ваша функция replaceAll изменяет строку, вы должны дать ему реальную строку, чтобы изменить.

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

Я нахожу ваше «упрощенное объяснение» довольно простым! – SimplyKnownAsG

1

Это должно устранить ошибку:

#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

Это правильно. Однако реальный вопрос заключается в том, почему исходный код является ошибкой, а не тем, что он делает. Что делает этот код, это то, что ожидает пользователь (было бы более очевидно, если replaceAll вернул некоторую другую информацию, такую ​​как сколько было заменено, так что имеет смысл, что код хочет игнорировать измененную строку). – user3080602

1

Если вы хотите, чтобы иметь возможность передавать временные переменные в качестве параметра, вы можете вернуть результат вместо:

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

Проблема с ваш код заключается в том, что вы пытаетесь ссылаться на временный объект с помощью не постоянной ссылки. Компилятор создает временные объекты для оценки выражения для временного хранения значения объектов (для параметра pas петь, возвращать значения из func и т. д.). Вы можете назначить адрес не постоянного объекта указателю const, потому что вы просто обещаете не менять что-то, что нормально менять. Но вы не можете назначить адрес объекта const объекту non-const, поскольку это позволит вам позже изменить объект. Правильный путь будет использовать переменный временный передать параметру

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

в @Umer и @John Написала

+2

Это несколько вводящее в заблуждение объяснение. Проблема заключается не в том, что строка в двойных кавычках является постоянной, проблема в том, что строки в двойных кавычках не относятся к типу std :: string, поэтому компилятор должен построить * временную строку * std ::, чтобы вызвать функция и правило в C++ - вы не можете привязать неконстантную ссылку на временную. Это же правило остановит этот код для компиляции 'string function_returning_a_string(); ... replaceAll (function_returning_a_string(), "n", "k"); ', хотя в этом случае не участвует const. – john

+0

Thnx @john fr уточнение :) – maximus

+0

К сожалению, временные данные не являются постоянными. Например, этот код является законным 'string function_returning_a_string(); ... function_returning_a_string() = "abc"; '. Правило заключается в том, что вы не можете привязывать неконстантную ссылку на временную, независимо от того, является ли временная константа или нет, не имеет значения. Если вы удалите '(который является константой)', тогда все в порядке. – john

Смежные вопросы