Như chúng ta đã biết, mã bên dưới không đúng định dạng vì thành viên x
thuộc lớp cơ sở phụ thuộc. Tuy nhiên, việc thay đổi x
thành this->x
trên dòng được chỉ định sẽ khắc phục lỗi.Quy tắc cho phép `this->` truy cập vào các thành viên của các lớp cơ sở phụ thuộc là gì?
template <typename T>
struct B {
int x;
};
template <typename T>
struct C : B<T> {
void f() {
int y = x; // Error!
}
};
int main() {
C<int> c;
c.f();
}
Tôi muốn giải thích về cách hành vi này được chỉ định trong tiêu chuẩn. Theo [temp.dep]/3:
Trong định nghĩa của một lớp hoặc lớp mẫu, nếu một lớp cơ sở phụ thuộc vào một mẫu tham số , phạm vi lớp cơ sở không kiểm tra trong tên không đủ tiêu chuẩn tra cứu hoặc tại điểm định nghĩa của mẫu lớp hoặc thành viên hoặc trong quá trình diễn giải mẫu lớp hoặc thành viên.
Điều này dường như giải thích tại sao chỉ sử dụng x
không thành công. Tên x
được tra cứu tại điểm định nghĩa và phạm vi lớp cơ sở không được kiểm tra. Tuy nhiên, nếu chúng ta sử dụng this->x
thì sao? Bây giờ tên x
là phụ thuộc và tra cứu của nó được hoãn cho đến khi instantiation. Nhưng đoạn trích dẫn dường như ngụ ý rằng x
không nên được tìm thấy thậm chí lúc instantiation, kể từ khi tra cứu của x
trong this->x
là vẫnkhông đủ tiêu chuẩn tra cứu.
Rõ ràng việc triển khai không hoạt động theo cách này và được hiểu rộng rãi rằng phạm vi lớp cơ sở là được tìm kiếm khi mẫu được khởi tạo.
- Tôi đã giải thích sai đoạn trích dẫn?
- Có đoạn nào chỉ định hành vi "đúng" không?
Đây không phải là tra cứu không đủ tiêu chuẩn (3.4.1 \ [basic.lookup.unqual \]), đây là tra cứu biểu thức truy cập thành viên lớp (3.4.5 \ [basic.lookup.classref \]). –
@ n.m. Cảm ơn, tôi đã không nhận ra tra cứu tên thành viên lớp là một loại tra cứu tên riêng biệt. Bạn nên làm cho câu trả lời đó. – Brian
Chính xác 'lớp cơ sở phụ thuộc' là gì? Trái với việc nói một lớp cơ sở độc lập? Có một điều như vậy? – EJP