6

Below is the code for find and replace a sub string from a string.But i am not able to pass arguments to the function.

Error Message :

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

please help with explanation

#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;
}
san45
  • 459
  • 1
  • 6
  • 15
  • 1
    You can't bind a temporary to a non-const reference. What's it supposed to change? – chris Oct 04 '13 at 05:10
  • 3
    The temporary of course. I've never really agreed with this rule, but I once got a reply from Bjarne Stroustrup himself saying that he felt to allow code to modify temporaries like this was 'too confusing'. – john Oct 04 '13 at 05:15

4 Answers4

7

A simplified explanation is that since your replaceAll function is changing a string, you must give it an actual string to change.

int main() {
    string str = "hellounny";
    replaceAll(str,"n","k");
    return 0;
}
john
  • 85,011
  • 4
  • 57
  • 81
1

This should remove the error:

#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;
}
Umer Farooq
  • 7,356
  • 7
  • 42
  • 67
  • 1
    This is correct. However the real question is why the original code is an error, rather than doing exactly what this does. What this code does is what the user expects (it would be more obvious if replaceAll returned some other information such as how many were replaced, so that it makes sense that the code wants to ignore the modified string). – user3080602 Aug 07 '15 at 21:58
1

If you want to be able to pass temporaries in as a parameter, you could return the result instead:

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");
goji
  • 6,911
  • 3
  • 42
  • 59
0

Problem with your code is that you are trying to reference a temporary object by using a non constant reference.Compiler creates temporary objects for evaluation of expression to temporarily store the objects value(for parameter passing,returning values from a func etc).You can assign the address of a non constant object to a const pointer because you're simply promising not to change something that is ok to change. But you can't assign the address of a const object to a non-const reference because this will allow you to modify the object later. Correct way will be to use a temp variable to pass the parameter

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

as @Umer and @john Wrote

mchouhan_google
  • 1,775
  • 1
  • 20
  • 28
  • 2
    That's a somewhat misleading explanation. The problem isn't that string in double quotes is constant, the problem is actually that strings in double quotes are not of type std::string, so the compiler has to construct a *temporary* std::string in order to call the function, and the rule in C++ is you cannot bind a non-const reference to a temporary. The same rule would stop this code compiling `string function_returning_a_string(); ... replaceAll(function_returning_a_string(), "n", "k");` even though in this case there's no const involved. – john Oct 04 '13 at 05:43
  • Thnx @john fr elaborating :) – mchouhan_google Oct 04 '13 at 05:49
  • Unfortunately temporaries are not constant. For instance this code is legal `string function_returning_a_string(); ... function_returning_a_string() = "abc";`. The rule is that you cannot bind a non-const reference to a temporary, whether the temporary is constant or not is irrelevent. If you remove '(which is a constant)' then it's OK. – john Oct 04 '13 at 05:59