string name1 = "Mary";
Let's unpick this, there are several things going on.
The token
"Mary"
taken alone is a string literal which roughly evaluates to the array
const char literal_array[5] = { 'M', 'a', 'r', 'y', 0 };
You can see why it's worth having some syntactic sugar - writing that out for every string would be awful.
Anyway, there are no " characters in there - they're used to tell the compiler to emit that string literal, but they're not part of the string itself.
Then, once we know what the right-hand side of the expression is, we can look at the left:
string name1 = "Mary"
is really
string name1(literal_array);
using the constructor
basic_string<char>::basic_string<char>(const char *)
I'm paraphrasing slightly, but it's item 5 here.
name1 < "Mary Jane"
Now we finally know what the left hand side is, we can look at this expression, which expands to
const char literal_array2[10] = { 'M', 'a', 'r', 'y', ' ', 'J', 'a', 'n', 'e', 0 };
operator< (name1, literal_array2)
which is the 9th overload here (at the time of writing), and which calls compare as
name1.compare(literal_array2)
which is described as doing the following:
4) Compares this string to the null-terminated character sequence beginning at the character pointed to by s, as if by compare(basic_string(s))
which takes us back to the first overload:
1) First, calculates the number of characters to compare, as if by
size_type rlen = std::min(size(), str.size()).
Then compares by calling
Traits::compare(data(), str.data(), rlen).
For standard strings this function performs character-by-character lexicographical comparison.
If the result is zero (the strings are equal so far),
note that this is the case when we've just compared "Mary" with "Mary" so far
then their sizes are compared as follows:
size(data) < size(arg) => data is less than arg => result <0
where "result <0" means operator< will return true.
"are not part of the string itself