Tôi đã ngạc nhiên khi mã sau đây biên dịch và chạy (vc2012 & gcc4.7.2)
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ó đú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)?
private
có một sự thuận tiện để mô tả các API theo cách mà trình biên dịch có thể giúp thực thi. Người dùng không có ý định ngăn chặn truy cập vào loại Bar
của người dùng Foo
, vì vậy nó không cản trở Foo
bất kỳ cách nào từ việc cung cấp quyền truy cập đó bằng cách trả lại một thể hiện của Bar
.
#include <iostream>
. ;-)
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" loại được trả về bởiBaz()
nếu bạn có thể giữ nó, bạn không thể đặt tên cho nó.