a reference of type "std::string&" (not const-qualified) cannot be initialized
When I try to compile the following functi开发者_如何学Pythonon I get the error.
string& foo(){
return "Hello World";
}
Error:
1 IntelliSense: a reference of type "std::string &" (not const-qualified) cannot be initialized with a value of type "const char [12]"
There are two problems with your code. First, "Hello World!"
is a
char const[13]
, not an std::string
. So the compiler has to
(implicitly) convert it to an std::string
. The result of a
conversion is a temporary (rvalue in C++-speak), and you cannot
initialize a reference to a non-const with a temporary. The second is
that even if you could (or you declared the function to return a
reference to const), you're returning a reference to something which
will immediately go out of scope (and thus be destructed); any use of
the resulting reference will result in undefined behavior.
The real question is: why the reference? Unless you're actually
referring to something in an object with a longer lifetime, with the
intent that the client code modify it (usually not a good idea, but
there are notable exceptions, like operator[]
of a vector), you should
return by value.
"Hello World" isn't a string, it is an array of char. The c++ compiler needs to convert this into a string value, not a string reference (because it's not a string), so your function should look like:
string foo(){
return "Hello World";
}
To expand (at the OP's request) the compiler does something like this:
string foo(){
char a[] = "Hello World";
string s( a );
return s;
}
The value s is copied out of the function by the std::string copy constructor.
You're instructing the compiler to return a temporary std::string created from the char array "Hello World". It needs to put this somewhere and have somebody responsible for cleaning it up. You can do that in a few ways:
- Return an auto_ptr
- Return a string object
- Return a const reference to a string object (although this does leave me with the question who cleans it up?)
- (c++0x only) Return a right-hand-reference to an std::string. (std::string &&)
The second would probably be the easiest. The compiler will use RVO (return value optimization) to remove the copy invoked by that.
Just do this.
const string foo() {
return string("Hello World");
}
I think you want:
string foo(){
return "Hello World";
}
Listen Carefully
To understand the issue, and its solution, you have to understand some working of the Compiler. But, don't worry, I will explain and will keep it simplest as possible.
string& foo() vs string foo()
In the first example, we want to return a "Reference" to an already created string, which should have a memory address (I mean, an lvalue). If we return, like this:
string& foo()
{
return "Example String";
}
It'll never work, because you may have got the reason. The String: "Example String" is a Temporary value, having no memory address, because it's not constructed yet. It has to be constructed somewhere, inside of any string variable, where it will be assigned to a memory address. Currently, it's having no memory address (I mean rvalue).
Similarly, in the 2nd case, if we do something like this:
string foo()
{
return "Example String";
}
Here, we are actually constructing a new Variable of type String, from where it's being called. For example, if we do something like this:
int main()
{
string Test = foo();
}
A string variable will be created on the Right Side of the Equality Operator, and the Data will be copied to the Test variable (If compiler optimization is disabled). But wait, there's something else too.
What is: const string& foo() ?
Here lies some Compiler's Magic
精彩评论