In that case, the optimal interface should take std::string&& no? But it's awkward.
But yeah, in a c++ codebase, good modern practices are often verbose and clunky.
IMO it's hard to beat pass by value considering both performance and cognitive load.
...but that requires the argument to be a type from a template D: so you'd have to write:
template<typename String = std::string>
void dosomething(String &&str)
...and that's not quite right either, since you'd want it to be either an rvalue reference or a const lvalue reference