W GCC rozumiem
so.cpp:8:27: error: expected '>'
if(this->b.foo < 1)
^
Tak więc kompilator uważa, że foo
ten wiersz odnosi się do klasy foo
powyżej i oczekuje argumentu szablonu. To jest podobne do tego, co widzisz.
Kiedy zmienisz na <=
, który leksemizuje tokenizator jako pojedynczy token. Następny etap nawet nie widzi a <
, więc nie jest przez to zagubiony.
Jeśli zmienisz klasę, aby nie miała takiej samej nazwy jak długo w bar
, oznacza to, że nie ma tego problemu. Również @ Jarod42 ma sugestie w swoim komentarzu do twojego pytania (więcej kwalifikacji lub parens).
Kompilatory są pisane etapami, gdzie każdy etap przekłada kod na lepszą reprezentację na następny, a każdy etap może robić coraz bardziej złożone rzeczy z tą reprezentacją.
Na początku kompilator „lekceważy” kod, który zamienia poszczególne znaki w pliku w strumień tokenów - uznałby tę linię za coś w rodzaju
// if(this->b.foo < 1)
- keyword(if)
- left-paren
- keyword(this)
- operator(->)
- name(b)
- operator(.)
A potem dociera do foo
. Powinno to chyba wystarczyć
- name(foo)
- operator(<)
- number(1)
- right-paren
Ale wydaje mi się, że kiedy widzi foo
, patrzy w przyszłość, widzi <
i fakt, który foo<class T>
istnieje i próbuje zrobić pojedynczy token, foo< ...
ale wtedy nie może go znaleźć >
.
To tylko przypuszczenie - może to być etap za leksemem, który próbuje znaleźć nazwy i może łączyć tokeny. W każdym razie wielokrotne użycie foo to oszukuje.
b.bar::foo
lub nawiasy ((this->b.foo) < 1
)