According to the C++ Standard (28.7 Sorting and related operations)
2 Compare is a function object type (23.14). The return value of the
function call operation applied to an object of type Compare, when
contextually converted to bool (Clause 7), yields true if the first
argument of the call is less than the second, and false otherwise.
Compare comp is used throughout for algorithms assuming an ordering
relation. It is assumed that comp will not apply any non-constant
function through the dereferenced iterator.
This lambda expression
auto comparator([](std::string a , std::string b) {return a.length() - b.length();} );
always returns (contextually converted value) true
if lengths of two strings are unequal.
So for this vector
std::vector<std::string> v {"y" , "yyyy" , "yy" ,
"yy" , "yyyyyyy" , "yyy"};
the lambda-expression returns false
for adjacent elements "yy"
and "yy"
at position 2
and 3
.
If for example you will place an intermediate value between positions 2 and 3 as for example
std::vector<std::string> v {"y" , "yyyy" , "yy" , "y",
"yy" , "yyyyyyy" , "yyy"};
then the first assertion
assert(false == std::is_sorted(v.begin() , v.end(),comparator));
fails.
Thus you need correctly to define the comparison function. For example
auto comparator( []( const std::string &a , const std::string &b )
{
return a.length() < b.length();
} );
Also the parameters of the lambda expression should be constant references.
Take into account that if your compiler supports C++ 17 then you could also rewrite the lambda expression the following way
auto comparator( []( const std::string &a , const std::string &b )
{
return std::size( a ) < std::size( b );
} );