Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is there no implicit conversion from std::string_view to std::string?

There is an implicit conversion from std::string to std::string_view and it's not considered unsafe, even though this surely may cause a lot of dangling references if programmer is not careful.

On the other hand, there's no implicit conversion from std::string_view to std::string using same argument but in the completely opposite fashion: because programmer may be not careful.

It's lovely that C++ has a replacement for a raw const char* pointer, while making it super confusing and stripped to the bone:

  • Implicit const char* -> std::string: OK
  • Implicit std::string_view -> std::string: NOPE
  • Assignment std::string = const char* : OK
  • Assignment std::string = std::string_view: OK
  • Appending std::string += const char* : OK
  • Appending std::string += std::string_view: OK
  • Concatenation const char* + std::string: OK
  • Concatenation std::string_view + std::string: NOPE
  • Concatenation std::string + const char*: OK
  • Concatenation std::string + std::string_view: NOPE

Am I missing something or is this a total nonsense?

In the end, how useful is this string view without all the crucial pieces that make it similar to const char*? What's the point of integrating it into the ecosystem of stdlib while not making the last step to make it complete? After all, if we need an object that represents a piece of a string we could write our own. Actually, a lot of libraries already have done that, years ago. The whole point of making something standard is to make it useful for widest range of use cases, isn't it?

Are they going to fix this in C++23?

like image 497
GreenScape Avatar asked Nov 28 '17 06:11

GreenScape


People also ask

Is std::string the same as string?

There is no functionality difference between string and std::string because they're the same type.

Why do we use std::string?

std::string class in C++ C++ has in its definition a way to represent a sequence of characters as an object of the class. This class is called std:: string. String class stores the characters as a sequence of bytes with the functionality of allowing access to the single-byte character.

What is String_view C++?

What is string_view ? Conceptually, string_view is only a view of the string and cannot​ be used to modify the actual string. When a string_view is created, there's no need to copy the data (unlike when you create a copy of a string).


1 Answers

The problem is that std::string_view -> std::string makes a copy of the underlying memory, complete with heap allocation, whereas the implicit std::string -> std::string_view does not. If you've bothered to use a std::string_view in the first place then you obviously care about copies, so you don't want one to happen implicitly.

Consider this example:

void foo1(const std::string& x) {     foo2(x); } void foo2(std::string_view x) {     foo3(x); } void foo3(const std::string& x) {     // Use x... } 

The function foo2 could've used a const std::string& parameter, but used a std::string_view so that it is more efficient if you pass in a string that isn't a std::string; no surprises there. But it's less efficient than if you'd just given it a const std::string& parameter!

  • When foo2 is called with a std::string argument (e.g. by foo1): When foo2 calls foo3, it creates a copy of the string. If it had a const std::string& argument, it could've used the object it already had.
  • When foo2 is called with a const char* argument: A std::string copy has to be made sooner or later; with a const std::string& parameter it gets made earlier, but overall there's exactly one copy either way.

Now imagine foo2 calls multiple functions like foo3, or calls foo3 in a loop; it's making exactly the same std::string object over and over. You'd want the compiler to notify you about this.

like image 75
Arthur Tacca Avatar answered Oct 17 '22 11:10

Arthur Tacca