Xcode completes correctly, but that is not what you expect. You actually answered the question without knowing. The function signature for the string substr() method, as you said, is:
string substr ( size_t pos = 0, size_t n = npos ) const;
All substr() arguments have default assignments, so for Xcode, s.substr() (without arguments), code completion for insertion is valid because it is really s.substr(0, s.npos) . You can confirm this with any number of standard C ++ functions with default arguments. The easiest way to see this is with any STL container constructor.
Take, for example, a vector . We all know that vectors can accept Allocator , but the default argument assigned by Allocator is "good enough" for most random purposes. Of course, two of the signatures for the vector constructors are:
explicit vector ( const Allocator& = Allocator() ); explicit vector ( size_type n, const T& value= T(), const Allocator& = Allocator() );
In both cases, the Allocator argument has a default assignment, and in the second, the T value has a default assignment. Now let's see what Xcode offers when building vector :

A sentence without a list of arguments is actually a constructor that accepts only Allocator . A sentence that takes only a size_type is actually a constructor that accepts size_type , T and Allocator .
Depending on how you think about it, this may or may not be an Xcode error. Ideally, you want to see add-ons with default arguments for simpler functions like substr() , but for STL container constructors, you probably almost never want to see them. Perhaps this may be an option, but I did not expect this to be fixed. I would gladly please you with a radar.