Vấn đề trình biên dịch C ++ với struct trong lớp mẫu


13

Đoạn mã sau không biên dịch với gcc hoặc clang.

template<class T>
class foo{};

template<class T>
class template_class_with_struct
{
    void my_method() {
        if(this->b.foo < 1);
    };

    struct bar
    {
        long foo;
    } b;
};

Thông báo lỗi là

error: type/value mismatch at argument 1 in template parameter list for 'template<class T> class foo'    
    8 |         if(this->b.foo < 1);

Lỗi là do lớp templat foo. Khi viết <= thay vì <1, nó cũng biên dịch.

Bất kỳ gợi ý đánh giá cao?

Trình biên dịch liên kết Trình biên dịch https://godbolt.org/z/v6Tygo


7
Tôi muốn nói rằng trình biên dịch lỗi nhưng msvc là người duy nhất chấp nhận nó: - / Demo . Có thể làm việc xung quanh b.bar::foohoặc dấu ngoặc đơn ( (this->b.foo) < 1)
Jarod42

Câu trả lời:


1

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 footrê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ó.


Tôi hiểu lời giải thích của bạn, nhưng không chắc nó có nghĩa là trình biên dịch nên hành xử theo cách đó không. Có lẽ đây là trường như lỗi cho các trình biên dịch khác nhau. Đôi khi bạn không thể biết các lớp mẫu nào nằm trong tiêu đề thư viện được liên kết (các tên phổ biến như cnt, Count, counter ...)
eactor

Tôi nghĩ đó là một lỗi, nhưng tôi không biết thông số kỹ thuật nói gì. Có tên từ các tiêu đề bên thứ 3 gây ra sự cố là một sự xuất hiện phổ biến trong C ++ - bạn thường có thể giải quyết với trình độ chuyên môn.
Lou Franco
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.