'C++ - As string literal is lvalue, why it can be passed to void PrintName(string&& name);? [duplicate]
void PrintName(string&& name) {
cout << "[rvalue] " << name << endl;
}
void PrintName(string& name) {
cout << "[lvalue] " << name << endl;
}
int main() {
string name{"Charles"};
PrintName(name); // [lvalue] Charles
PrintName("Charles"); // [rvalue] Charles
}
I overloaded the PrintName to accept both the rvalue and lvalue.
When I call it with a lvalue name, it works fine and outputs [lvalue] Charles;
When I call it with "Charles" directly, it chooses to run the rvalue version and outputs [rvalue] Charles.
However, I heard that the string literal is lvalue, so why doesn't "Charles" call the lvalue version of the PrintName?
And, how can we write some code to prove that the string literal is lvalue?
With the help of the comments and answers, I finally figured out to write a piece of code to prove that a string literal is a lvalue
typedef const char stringliteral[8];
void PrintName(stringliteral&& name) {
cout << "[rvalue] " << name << endl;
}
void PrintName(stringliteral& name) {
cout << "[lvalue] " << name << endl;
}
Call PrintName by "Charles" will run the rvalue version.
Solution 1:[1]
"Charles" is not a string, it's const char [8]. When call PrintName, It implicitly create a string, so it's a right value.
Solution 2:[2]
The string literal is not an . The reason is that string literals are stored in the lvalue.rodata (read-only data) section (see this site for more info) and thus cannot be modified, hence it is an rvalue.
Update: I stand corrected on the matter of string literals not being lvalues: see here.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Remy Lebeau |
