In my opinion, sf::String member functions taking iterators are quite important. This includes the constructor, so that one can easily create sf::String from iterator ranges, independent of the underlying container.
std::string buffer;
sf::String subString(buffer.begin(), buffer.begin() + 5);
Substrings are easy to implement provided the iterator interface. At the moment, there is no way to add characters except using Insert(), which is not helpful for substrings, because it only accepts complete sf::String objects. The workaround is rather ugly:
sf::String SubString(const sf::String& source, unsigned int begin, unsigned int length)
{
std::basic_string<sf::Uint32> buffer(source.Begin() + begin, source.Begin() + begin + length);
return sf::String(buffer);
}
I personally find the single-character constructors rather questionable, but I understand they are a simple way to allow concatenations without masses of + and += overloads. However, the constructors could be extended to take a second parameter (similar to std::string, but in reverse order), allowing construction of fillers like whitespaces or dots:
sf::String(char fillCharacter, size_t length = 1);
Finally, I don't see much benefit in the coexistence of To...() methods and conversion operators. Are the two following operators really required? I wouldn't provide them just for convenience. Multiple functions doing the same thing often cause confusion at users – as well as some implicit conversions.
operator std::string()
operator std::wstring()