2012-02-10 27 views
13

Câu hỏi tiếp theo tới this one.Tại sao trình biên dịch chọn hàm tạo lớp cơ sở bên trong danh sách đối số mẫu?

Về cơ bản, trong đoạn mã sau, tại sao các trình biên dịch nghĩ rằng B bên A<B> trong constructor C s tham khảo (không truy cập được) constructor của lớp B cơ sở?

struct B{}; 

template <typename T> 
struct A : private T{}; 

struct C : public A<B>{                    
    C(A<B>); // ERROR HERE 
}; 

Live example on Ideone. Output:

prog.cpp:1:9: error: 'struct B B::B' is inaccessible
prog.cpp:7:7: error: within this context

Lưu ý rằng các lỗi tương tự bật lên nếu bạn thay đổi đối số nhà xây dựng để A<B*>, A<B&> hoặc thậm chí A<const B>. Cũng lưu ý rằng ba của MSVC10, GCC 4.7 và Clang 3.1 ToT sẽ lỗi, vì vậy nó phải là một cái gì đó trong spec C++. Nó là gì?

+0

Tôi không biết tại sao bạn tạo chủ đề chính xác tương tự! Bạn có thể đã chỉnh sửa chủ đề đó để làm chủ đề đó tốt hơn. – Nawaz

+3

@Nawaz: Về cơ bản nó là một câu hỏi khác. Tôi hỏi "tại sao", câu hỏi khác hỏi "phải làm gì". – Xeo

+0

Người đàn ông, tôi đã bị cắn bởi điều này nhiều hơn một lần với 'class A: private NotCopyable {class B: private NotCopyable {}}; '. Tôi đoán nó trông lên các biểu tượng trong phạm vi lớp trước khi nhìn vào phạm vi toàn cầu. –

Trả lời

15

Tiêu chuẩn cho phép tên lớp được tiêm ít truy cập hơn tên gốc. Đây thậm chí còn đề cập trong một lưu ý trong §11.1/5, cùng với một ví dụ:

[ Note: In a derived class, the lookup of a base class name will find the injected-class-name instead of the name of the base class in the scope in which it was declared. The injected-class-name might be less accessible than the name of the base class in the scope in which it was declared. —end note ]

[ Example:

class A { }; 
class B : private A { }; 
class C : public B { 
    A *p; // error: injected-class-name A is inaccessible 
    ::A *q; // OK 
}; 

end example ]

Truy cập A không đủ tiêu chuẩn sử dụng tên tiêm, trong đó không thể truy cập bởi vì nó xuất phát từ thừa kế riêng. Việc truy cập A đủ điều kiện sử dụng tên được khai báo, có thể truy cập được trong phạm vi toàn cục.

Các vấn đề liên quan