No GCC, recebo
so.cpp:8:27: error: expected '>'
if(this->b.foo < 1)
^
Portanto, o compilador pensa que a foo
linha nessa linha se refere à classe foo
acima e espera um argumento de modelo. Isso é semelhante ao que você está vendo.
Quando você altera para <=
, que é tokenizado pelo lexer como um único token. O próximo estágio nem vê um <
, por isso não é confundido com ele.
Se você alterar a classe para não ter o mesmo nome que o long in bar
, ele não terá esse problema. Além disso, @ Jarod42 tem sugestões no seu comentário à sua pergunta (mais qualificação ou parens).
Os compiladores são escritos em estágios, onde cada estágio converte o código em uma melhor representação para o próximo, e cada estágio pode fazer coisas cada vez mais complexas com essa representação.
No início, o compilador "anexa" o código, que transforma os caracteres individuais no arquivo em um fluxo de tokens - veria essa linha como algo como
// if(this->b.foo < 1)
- keyword(if)
- left-paren
- keyword(this)
- operator(->)
- name(b)
- operator(.)
E então chega ao foo
. Provavelmente deveria fazer
- name(foo)
- operator(<)
- number(1)
- right-paren
Mas, parece-me que quando vê foo
, olha para frente, vê o <
fato que foo<class T>
existe e tenta criar um único token, foo< ...
mas não consegue encontrar o >
que o completa.
Isso é apenas um palpite - pode ser um estágio passado do lexer que tenta encontrar nomes e pode combinar tokens. De qualquer forma, os múltiplos usos do foo estão enganando-o.
b.bar::foo
(this->b.foo) < 1