String algorithms and locale
I think I'd prefer to have the user pass a locale instead of a facet. In most typical cases, a user will deal only with locales, not with the individual facets that make up a particular locale. It's also relatively easy for a user to create a locale on demand, so the code looks something like:

std::string input{"Now is the time for every good man to come of the aid of his country."};

std::string result = upper(input, std::locale("en-us"));


or:

std::string result = upper(input, std::locale(""));


...though I suppose we can probably expect that the default parameter will be used a lot more often than not, in which case all of this is moot.

Anyway, using a locale as the parameter lets us move the use_facet call inside the function body and use auto for it instead of writing out its full type:

auto const&amp; f = std::use_facet&lt;std::ctype&lt;typename String::value_type&gt;&gt;(locale);


Not a huge change, but somewhat simpler nonetheless. Given that you're depending on String being contiguous and supporting random access, it might be worth considering making use of that a little more explicitly, by replacing &amp;str[0]+str.size() with &amp;str[str.size()].

Although I'm somewhat on the fence about it, I'm also less than excited about the idea of using a trailing return type when it's not actually necessary. Maybe it's just a sign of my age, but I still tend to prefer the return type in its traditional location when possible.

Putting all those together, we'd end up with something on this order:

template&lt;typename String&gt;
String upper(String str, std::locale const &amp;locale = std::locale())
{
    auto const&amp; f = std::use_facet&lt;std::ctype&lt;typename String::value_type&gt;&gt;(locale);
    f.toupper(&amp;str[0], &amp;str[str.size()]);
    return str;
}


I'm not sure anybody could call that a huge improvement, but I do think it's at least a minor one, especially in convenience to the user.