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