switch is a strange construct. It comes from C, and Java and C# adopted it too, so it is not considered totally "non-OO".
switch on state which changes is a valid OO concept, but often is used for switching based on type.
In particular the compiler usually creates a "jump" table which means it is O(1) what block of code gets called, unlike a nested "if" statement. You may have multiple values (not including default) jump to the same point, thus code blocks "run into" each other unless you explicitly insert a "break" statement.
This is how it was done in C and has been retained for C++.
With regards to the value in the switch, it must be a numeric value but does not have to be a constant. In your case i++
evaluates to 0 but increments i to 1. This is well-defined behaviour and there is no issues with sequence points here.