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

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.

Leave a Comment