Reputation: 2144
The code below:
void test(string &s){ // if the argument is "string s", it works
return test(s+',');
}
The compiler reports cannot find the function: test(std::basic_string).
I think the compiler would create a temporary string (== s+','), and I can pass its reference. But it seems I am wrong. I do not know why I cannot pass the reference of this temporary string.
Upvotes: 2
Views: 914
Reputation: 254431
You can't bind a temporary to a non-constant reference. You could either take the argument by const
reference (or, as you point out, by value)
void test(string const & s){ // or string s
return test(s+',');
}
or use a named variable rather than a temporary
void test(string & s){
std::string s2 = s + ',';
return test(s2);
}
As noted, at great length, in the comments, this code has undefined runtime behaviour and shouldn't be used in "real" code; it's purpose is just a minimal example of how to fix the observed compilation error
Upvotes: 2
Reputation: 2349
Standard C++ does not allow a non-const lvalue reference to be bound to an rvalue. In your example, the result of the expression s+','
is a temporary and thus an rvalue, so the compiler is required to discard the overload of test
expecting an lvalue reference, leaving it no overload available to call. That's why it complains about not being able to find the function test
.
To solve this issue you have to provide an overload whose parameter may be bound to an rvalue. As you realized yourself, expecting an argument by-copy works, but it may imply unnecessary overhead by calling copy/move-ctors. A better option would be to expect the argument by reference. Since const lvalue references may be bound to rvalues, declaring the function as follows solves the problem.
void test(std::string const& s)
Upvotes: 0
Reputation: 517
But first you should have seen this question String Concatenation
concatenating strings using "+" in c++
Alternative Solution
void test(string &s)
{
s.append(",");
return test(s);
}
Upvotes: 0
Reputation: 49976
make it const:
void test(const std::string &s){ // if the argument is "string s", it works
return test(s+',');
}
Upvotes: 2