Это не имеет ничего общего с приоритетом оператора.
Вы используете <<, что является синтаксическим сахаром для вызова функции: </p>
std::cout << ((i != 0) ? "Not zero " : "zero ") << ++i << std::endl;
// Equivalent too:
operator<<(operator<<(operator<<(std::cout, ((i != 0) ? "Not zero " : "zero ")), ++i), std::endl);
Единственное правило здесь состоит в том, что параметр должен быть полностью оценен перед вызовом функции. Нет никаких ограничений относительно того, в каком порядке оцениваются параметры или даже если их оценка чередуется с вызовами (или даже частично оценивается).
Интерпретация 1:
1) ((i != 0) ? "Not zero " : "zero "))
2) ++i
3) operator<<(std::cout, (1));
4) operator<<((3), (2));
5) operator<<((4), std::endl);
Интерпретация 2:
1) ++i
2) ((i != 0) ? "Not zero " : "zero "))
3) operator<<(std::cout, (2));
4) operator<<((3), (1));
5) operator<<((4), std::endl);
Интерпретация 3:
1) ((i != 0) ? "Not zero " : "zero "))
2) operator<<(std::cout, (1));
3) ++i
4) operator<<((2), (3));
5) operator<<((4), std::endl);
Рассматривая толкование 1 как ссылку:
Правила, которые должны применяться:
A) (1) happens before (3)
B) (2) happens before (4)
C) (3) happens before (4)
D) (4) happens before (5)