gust
gust

Reputation: 945

Correct way to use reference lvalues

My code is the following:

void parentheses (int n, string& str, int left, int right){

    ... irrelevant... 

}
void solve(int n){
    parentheses(n,"",0,0);
}

However, this will give me an error, telling me that cannot bind non-const lvalue reference of type std::__cxx11::string& ... to an rvalue of type ‘std::__cxx11::string. In this case, if I still want to pass the string in as a reference, how should I modify my functions? I don't want to make them const because I want to functions to modify the original string, and I want them to be & precisely because I want to edit their values.

Upvotes: 1

Views: 208

Answers (5)

jignatius
jignatius

Reputation: 6494

The function parentheses expects an lvalue in the std::string parameter, i.e. a named variable. However, you have supplied an rvalue (temporary) in this call:

parentheses(n,"",0,0);

An empty string object is created and passed to parentheses. You can avoid this problem by changing the definition of parentheses like so:

void parentheses (int n, const string& str, int left, int right)

Here str will bind to an rvalue/temporary, but you won't be able to change its value in the function. However, if you want to change the value of str you have to define a string variable and pass that to the function.

Example:

void solve(int n){
    std::string str;
    parentheses(n,str,0,0);
}

Note: no need to assign str to "" as a string is empty by default.

Upvotes: 2

Remy Lebeau
Remy Lebeau

Reputation: 597670

Your parentheses() function takes a non-const reference to a std::string object, so it expects an actual std::string object on the other side of the reference - an lvalue (something that can be assigned to).

But your solve() function is not passing a std::string object, it is passing a string literal instead. So the compiler creates a temporary std::string object - an rvalue - which then fails to bind to the reference, because a temporary object can't be bound to a non-const reference, only to a const reference. That is what the error message is telling you:

cannot bind non-const lvalue reference of type std::__cxx11::string& ... to an rvalue of type ‘std::__cxx11::string

solve() needs to explicitly create an actual std::string object to pass to parentheses():

void solve(int n){
    std::string s = "";
    parentheses(n,s,0,0);
}

Upvotes: 2

Amadeus
Amadeus

Reputation: 10665

If you want to change the values of your string for any string that is passed as a paramenter (lvalue, as well rvalue), just initialize a variable with the intended content and pass it to your function.

But if you want to treat lvalue strings diferently from rvalue strings, just overload your original function. i.e.:

void parentheses (int n, string& str, int left, int right){
    ... irrelevant... // change strings values as desired
}

void parentheses (int n, string&& str, int left, int right){
    ... irrelevant... // string as rvalue
}

Upvotes: 1

user10957435
user10957435

Reputation:

I'm not really sure what the purpose is of passing "" by reference is, as any value put there will get lost.

Anyway, to answer your question, create a variable and pass it instead:

void solve(int n){
    std::string tmp = "";
    parentheses(n,tmp,0,0);
}

If you don't care about the value stored in tmp, you can just ignore it. But you need some type of variable there, even if you don't care about what gets eventually put there by the routine.

Upvotes: 2

stylo
stylo

Reputation: 506

the function needs a memory to change, you didn't specify which. declare a string to hold what you want to pass and where to get the output to.

string s = "";

and pass it to the function

Upvotes: 2

Related Questions