Должен & = всегда интерпретироваться как оператор?
Я был кодированием и случайно оставил пробел между константой ссылки и значением по умолчанию. Я был удивлен, увидев, что это вызвало ошибку в Intellisense, поэтому я скомпилировал его, и, конечно же, он не работает в GCC 4.3.4, 4.5.1 или 4.7.2 и не работает в Visual Studio 2012.
Здесь показан эквивалентный образец, демонстрирующий ошибку:
struct S {
S(const int &= 5){}
};
int main(){}
Это дает следующую ошибку в GCC и аналогичные в MSVC:
error: ожидаемый ',' или '...' перед '& =' токеном
Я предполагаю, что это потому, что &=
рассматривается как оператор, но я не знаю точно, что искать в стандарте, чтобы найти больше информации об этом случае. & = просто появляется информация о операторах.
Будучи любопытным, я решил поменять его на ссылку rvalue:
S(int &&= 5){}
Как ни странно, это компилируется как на GCC 4.7.2, так и на MSVC, что означает, что & = не всегда лексически парно как оператор.
Почему он работает с ссылкой rvalue, но не ссылкой на lvalue, и что стандарт должен сказать по этому вопросу?
Ответы
Ответ 1
Это обычно известно как "принцип наибольшего соответствия" или "максимальный munch" . Поскольку &&
- действительный токен, а &&=
- нет (нет обозначения составного присвоения для &&
), самый длинный токен, начинающийся с &&=
, равен &&
; после этого не будет возможности для &=
рассматриваться как один токен.
Этот принцип распространен для многих языков, хотя часто есть исключения. Например, в С++ 11 >>
будет анализироваться как >
, а затем >
в контексте, например std::vector<std::vector<int>>
.
Ответ 2
Парсер просто работает слева направо, независимо от ассоциативности, поэтому в первом примере первый полный токен, который он находит, - это &=
. (В этот момент синтаксический анализатор еще не проверяет более крупные конструкции, поэтому все, что он знает, это то, что там есть токен.)
Во втором примере найденный токен &&
. Поскольку &&=
не является токеном!