No need for moves or constructing temporary std::string's, but I think it actually just does effectively the same thing as before.
That entirely depends on what the user has when they call your constructor. So lets consider your case 1 (std::string) and case 2 (std::string_view). In both cases, the eventual result is a std::string. Also, this analysis will ignore small string optimization.
So here are some options we can look at:
The user has a string literal.
in case 1, there will be a copy into a std::string parameter, followed by a move into the std::string in the class.
In case 2, there will be a copy of a pointer and size, followed by a copy of the characters into the std::string in the class.
In both cases, the length of the literal must be computed via char_traits::length at some point. If the user uses a UDL ("some_string"s or "some_string"sv) to compute the argument before passing it, then you can avoid the runtime char_traits::length call.
So in this case, they're basically the same.
The user has a std::string lvalue which they want to keep the value of.
In case 1, there will be a copy into the std::string parameter, followed by a move into the std::string member.
In case 2, there will be a copy of a pointer and size into the std::string_view parameter, followed by a copy of the characters into the std::string in the class
In both cases, the length is not computed, since std::string knows its length. Again, in this case, they're the same.
The user has a std::string value they want to move into the object. So this is either a prvalue or an explicit std::move.
In case 1, there will be a move-construction of the parameter, followed by the move-construction of the member.
In case 2, there will be a copy of a pointer and size, followed by a copy of the characters into the std::string member.
See the difference? In case 1, no characters ever get copied; there are only moves. This is because what the user has and what your class needs are identical. So you get the most efficient transfer possible.
In case 2, characters must get copied, because the string_view parameter has no idea that the user doesn't want to keep the string around. Therefore, neither does the constructor of the string member being invoked.
When you use an intermediary for a transfer where the source and destination types are the same, then you can introduce an inefficiency. If the user has the type you actually intend to use, then it is better performance-wise for your interface to express that type directly. If you use a view intermediary, then information and intent between the caller and the callee can get lost.
string_view is a lingua-franca type; it is primarily intended for when you want to use an array of characters without forcing the user to use a specific string type. For a use case where you intend to keep those characters around beyond the function call, a lingua-franca type is is sub-optimal because the only thing you can do to preserve them is copy them into your own string.
Unless it is important to keep std::string (or whatever string type you use) out of your interface, or if it's impossible for the user to directly pass the type you're storing the characters in (you may be storing an array, for example), you should use it as the parameter type.
But of course, this is all micro-optimization territory. Unless this class is being used a whole bunch, the difference is trivial.
string_viewshould be slightly faster than a rawchar*as it avoids the need for astrlencallstd::string_viewfromchar*not callstrlen? If not how does it know the length of the string?std::string(it doesn't actually say in your question).