Trong GCC, tôi nhận được
so.cpp:8:27: error: expected '>'
if(this->b.foo < 1)
^
Vì vậy, trình biên dịch nghĩ rằng foo
trên dòng đó đề cập đến lớp foo
ở trên và đang mong đợi một đối số mẫu. Điều này tương tự với những gì bạn đang thấy.
Khi bạn thay đổi nó thành <=
mã thông báo được mã hóa bởi lexer dưới dạng một mã thông báo duy nhất. Giai đoạn tiếp theo thậm chí không nhìn thấy a <
, vì vậy nó không bị nhầm lẫn bởi nó.
Nếu bạn thay đổi lớp thành không có cùng tên với tên dài bar
, thì nó không có vấn đề này. Ngoài ra, @ Jarod42 có đề xuất trong nhận xét của anh ấy cho câu hỏi của bạn (nhiều bằng cấp hoặc parens hơn).
Trình biên dịch được viết theo các giai đoạn, trong đó mỗi giai đoạn chuyển mã thành biểu diễn tốt hơn cho giai đoạn tiếp theo và mỗi giai đoạn có thể thực hiện nhiều việc phức tạp hơn với biểu diễn đó.
Khi bắt đầu, trình biên dịch "lexes" mã, biến các ký tự riêng lẻ trong tệp thành một luồng mã thông báo - nó sẽ xem dòng này giống như một dòng
// if(this->b.foo < 1)
- keyword(if)
- left-paren
- keyword(this)
- operator(->)
- name(b)
- operator(.)
Và sau đó nó được foo
. Nó có lẽ nên làm
- name(foo)
- operator(<)
- number(1)
- right-paren
Nhưng, nó trông giống như khi tôi nhìn thấy foo
, nó nhìn về phía trước, nhìn thấy <
và thực tế foo<class T>
tồn tại và nó cố gắng tạo ra một mã thông báo duy nhất foo< ...
nhưng sau đó nó không thể tìm thấy >
để hoàn thành nó.
Đây chỉ là một phỏng đoán - nó có thể là một giai đoạn vượt qua lexer cố gắng tìm tên và có thể kết hợp các mã thông báo. Trong mọi trường hợp, việc sử dụng nhiều foo là đánh lừa nó.
b.bar::foo
hoặc dấu ngoặc đơn ((this->b.foo) < 1
)