I am not 100% that the following code is semantically correct:
#include <iostream>
#include <experimental/string_view>
int main()
{
std::string str = "lvalue string";
std::experimental::string_view view_lvalue(str);
std::experimental::string_view view_rvalue(std::string{"rvalue string"});
std::cout << view_lvalue << '\n' << view_rvalue << '\n';
}
Question: Can I legally bind a rvalue to std::experimental::basic_string_view, or is it just UB? If yes, how does it work? As far as I know, a rvalue does not bind to a const
reference (which I assume the view holds to the original string) via the constructor, so I thought that at the end of the statement std::experimental::string_view view_rvalue(std::string{"rvalue string"});
the reference will be dangling. Does string_view
use a more sophisticated approach?
I am asking this because I am trying to write a similar view for some matrix class, and don't yet know how to deal with rvalues (I can disable them of course, but I don't think it's the best approach).
If cpprefernce is correct then this is UB. std::string_view
has
A typical implementation holds only two members: a pointer to constant
CharT
and asize
.
And the constructor has
Constructs a view of the first
str.size()
characters of the character array starting with the element pointed bystr.data()
.
So if string_view
just points to the underlying char array of the provided string then we will have a dangling pointer once the expression ends and the temporary is destroyed.
As pointed out in the comments one reason this behavior may have been allowed is so you can pass a string_view
to a function and construct that string_view
from a temporary string