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
foo2is called with astd::stringargument (e.g. byfoo1): Whenfoo2callsfoo3, it creates a copy of the string. If it had aconst std::string&argument, it could’ve used the object it already had. - When
foo2is called with aconst char*argument: Astd::stringcopy has to be made sooner or later; with aconst std::string¶meter 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.