Reputation: 47
So I was writing a program yesterday, and I encountered a problem that when I use a reference without const
, it'll be an error whenever I tried to call that function later. For example:
bool is_vowel(const string& s) //OK;
bool is_vowel(string& s) //Error!
{
if (s == "A" || s == "a") return true;
if (s == "E" || s == "e") return true;
if (s == "I" || s == "i") return true;
if (s == "O" || s == "o") return true;
if (s == "U" || s == "u") return true;
if (s == "Y" || s == "y") return true;
return false;
}
And considering the following that calls this function: (for simplicity, I've cut out a huge chunk of the original code, so don't focus on the logic here)
int FRI_Syllables(const string& s)
{
int syllables = 0;
for (int n = 0; n < s.length(); n++)
if (is_vowel(s.substr(n, 1)))
syllables ++;
}
return syllables;
}
So when I use this function, the line that calls is_vowel
when I don't use const
will return a compile-time error saying "No matching function for call to 'is_vowel'".
I know why references with const
here works; what I don't understand is why the one without doesn't.
And another thing that makes me more confusing is that in the FRI_Syllables
function, the references work with AND without the const
. So considering a part of the code in the main function that calls this function:
int main()
{
//rest of the code
int syllables = 0;
for (int i = 0; i < words.size(); i++)
syllables += FRI_Syllables(words[i]);
//rest of the code
}
This won't return any error whether I use int FRI_Syllables(const string& s)
or int FRI_Syllables(string& s)
. So why the differences? Why would references without const
sometimes work and others don't?
Upvotes: 0
Views: 88
Reputation: 477010
A non-const lvalue reference variable only binds to lvalues, not to rvalues. By contrast, a const lvalue reference binds to both lvalues and rvalues.
Since the result of s.substr(n, 1)
is an rvalue (a "temporary value"), it cannot bind to a non-constant lvalue reference.
The reasoning behind this language design choice is that the purpose of a non-constant lvalue reference is to allow you to change the object that's being referred to, but when that object is temporary, the changes would be lost immediately, so this is basically never what you could have intended.
Upvotes: 3