For calls (as opposed to returns): If you use std::move, yes. Otherwise, no. But using std::move is similar to changing the type in that it requires noticing the problem first.
> Passing a reference means the optimizer cannot optimize accesses, because it doesn't know what other pointers might be aliasing it. string_view has the same problem.
For `const std::string &`, the optimizer has to assume that the string pointer and length could change, which is indeed a problem as it has to keep reloading them if you call, e.g., `c_str()` or `size()` multiple times (with other things in between). For both `const std::string &` and `std::string_view`, the optimizer has to assume that the string data could change, but not the pointer or length, which is much less of a problem because you don't usually repeatedly load the same piece of string data in a loop. Therefore, `std::string_view` is a decent choice.
Passing `std::string` by value does indeed have the advantage that the compiler indeed could theoretically assume the string data is not aliased. But I just checked and none of Clang, GCC, MSVC, or ICC actually do so: