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;
}
2
  • 1
    You can't bind a temporary to a non-const reference. What's it supposed to change? Commented Oct 4, 2013 at 5: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'. Commented Oct 4, 2013 at 5:15

4 Answers 4

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;
}
Sign up to request clarification or add additional context in comments.

1 Comment

I find your "simplified explanation" quite simple!
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;
}

1 Comment

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).
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");

Comments

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

3 Comments

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.
Thnx @john fr elaborating :)
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.