Reputation: 11555
Today I see this piece of code and I'm wondering to know what it is exactly doing this const reference in an assignment where a new object is created. (I don't know how to name this kind of assignments.)
std::string const& p = s.c_str(); // s is a std::string
I understand that something like std::string const& p = s;
will create a reference p
to s
, but in the line shown we are creating a new object (using the raw pointer from std::string::c_str
).
I've made a MCVE in Coliru with this:
#include <iostream>
#include <string>
void foo(std::string const& s)
{
std::string const& p = s.c_str(); // << here
std::cout << s << " " << p << " " << &s << " " << &p << std::endl;
}
int main()
{
foo("hello");
}
And, as expected the output is showing that a new object was created:
hello hello 0x7ffdd54ef9a0 0x7ffdd54ef950
So, my question is: Is this actually doing something I'm not able to see? Does it have any problem (like a dangling reference) in the code?
Upvotes: 2
Views: 130
Reputation: 1
From std::string::c_str's documentation
, it returns:
a pointer to an array that contains a null-terminated sequence of characters (i.e., a C-string) representing the current value of the string object. That is, a
const char*
.
So when you wrote:
std::string const& p = s.c_str();
In the above statement, the const char*
that was returned on the right hand side is used to create a temporary object of type std::string
using a converting constructor that takes const char*
as argument.
Next, the lvalue reference p
on the left hand side is bound to that temporary obect. And in doing so, the lifetime of the temporary is extended.
To answer your last question, there is no dangling reference in your program.
Upvotes: 4
Reputation: 311048
In fact this construction
std::string const& p = s.c_str();
does not differ essentially from
std::string const p( s.c_str() );
but is more confusing.
As for the output of this statement
std::cout << s << " " << p << " " << &s << " " << &p << std::endl;
then there are outputted two different addresses. The first one is the address of the parameter s
and the second one is the address of the temporary object of the type std::string
created in this declaration
std::string const& p = s.c_str();
by means of the conversion constructor
basic_string(const charT* s, const Allocator& a = Allocator());
Upvotes: 3