Consider a function which converts a std::string to lower case. In order to use the move-constructor where applicable, and the copy-constructor otherwise, it may seem like two functions are required:
// Argument, s, is a const referenceauto str_to_lower(const std::string& s) -> std::string { auto clone = s; for(auto& c: clone) c = std::tolower(c); return clone;}// Argument, s, is an r-valueauto str_to_lower(std::string&& s) -> std::string { for(auto& c: s) c = std::tolower(c); return s;}
However, by taking the std::string by value instead, we can write one function which covers both cases:
auto str_to_lower(std::string s) -> std::string { for(auto& c: s) c = std::tolower(c); return s;}
Let's see why ...