This is the code from c++ primer:
string::size_type findChar(const string &s, char c, string::size_type & occurs){
auto ret = s.size();
occurs = 0;
for (decltype(ret) i = 0; i != s.size(); ++i){
if (s[i] == c){
if (ret == s.size())
ret = i;
occurs++;
}
}
return ret;
}
int main () {
string::size_type ctr;
cout << findChar("hello, world!", 'o', ctr);
}
An error happened after removing const from const string &s.
error: cannot bind non-const lvalue reference of type 'std::__cxx11::string&' {aka 'std::__cxx11::basic_string&'} to an rvalue of type 'std::__cxx11::string' {aka 'std::__cxx11::basic_string'} cout << findChar("hello, world!", 'o', ctr);
I wonder, in this case, what behaviors of compiler does the const keyword change? Thanks for helping me.
A string literal like "hello, world!" is not a std::string. So to call your function the compiler has to create a std::string for you. Such an object is called a temporary. So in the first case the compiler uses "hello, world!" to create a std::string and then binds that temporary string to reference parameter s.
However C++ has a rule that you cannot bind a temporary to a non-const reference. But when you change s from const std::string& to std::string& you are asking the compiler to do exactly that. This is what the error message is telling you.
If you changed your code to this
string::size_type ctr;
string hello = "hello, world!";
cout << findChar(hello, 'o', ctr);
it will now compile even without const. The difference here is that the compiler is no longer creating a temporary std::string (because hello is already a std::string). So the rule about temporaries and non-const references doesn't apply.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With