From C++20 (draft N4860) [lex.pptoken]/3.3
— Otherwise, the next preprocessing token is the longest sequence of characters that could constitute
a preprocessing token, even if that would cause further lexical analysis to fail, ...
and [lex.pptoken]/6
[Example: The program fragment x+++++y is parsed as x ++ ++ + y, which, if x and y have integral types,
violates a constraint on increment operators, even though the parse x ++ + ++ y might yield a correct
expression. —end example]
So, it is a rule of the language, that the +
goes with the variable, because the ++
is first grouped together.
Funnily, this reminds me of an old problem where: std::vector<std::vector<int>> a
used to cause problems because >>
would be one token instead of two (since it's supposed to be the longest sequence of characters). This is addressed by [temp.names]/3
When a name is considered to be a template-name, and it is followed by a <, the < is always taken as the
delimiter of a template-argument-list and never as the less-than operator. When parsing a template-argumentlist,
the first non-nested > is taken as the ending delimiter rather than a greater-than operator. Similarly,
the first non-nested >> is treated as two consecutive but distinct > tokens, the first of which is taken as the
end of the template-argument-list and completes the template-id. [Note: The second > token produced by this
replacement rule may terminate an enclosing template-id construct or it may be part of a different construct
(e.g., a cast). —end note]