tôi đã bằng cách nào đó ngạc nhiên rằng đoạn mã sau biên dịch và chạy (vc2012 & gcc4.7.2)Tại sao tôi có thể sử dụng tự động trên một loại riêng tư?
class Foo {
struct Bar { int i; };
public:
Bar Baz() { return Bar(); }
};
int main() {
Foo f;
// Foo::Bar b = f.Baz(); // error
auto b = f.Baz(); // ok
std::cout << b.i;
}
Có đúng là mã này biên dịch tốt? Và tại sao nó lại đúng? Tại sao tôi có thể sử dụng auto
trên một loại riêng tư, trong khi tôi không thể sử dụng tên của nó (như mong đợi)?
Quan sát rằng 'f.Baz i'() cũng là OK, như là 'std :: cout << typeid (f.Baz()). name() '. Mã bên ngoài lớp có thể "nhìn thấy" kiểu được trả về bởi 'Baz()' nếu bạn có thể giữ nó, bạn không thể đặt tên nó. –
Và nếu bạn nghĩ nó kỳ quặc (bạn có thể làm như vậy, nhìn thấy khi bạn đang hỏi về nó) bạn không phải là người duy nhất;) Chiến lược này rất hữu ích cho những thứ như [Safe-Bool Idiom] (http: // www .artima.com/cppsource/safebool.html). –
Tôi nghĩ rằng điều cần nhớ là 'private' là có một sự thuận tiện cho việc mô tả các API theo cách mà trình biên dịch có thể giúp thực thi. Nó không có ý định ngăn chặn truy cập vào kiểu 'Bar' bởi người dùng' Foo', vì vậy nó không cản trở 'Foo' bằng cách cung cấp truy cập đó bằng cách trả về một thể hiện của' Bar'. –