Xét đoạn mã sau:Có sử dụng không gian tên gây ra ẩn tên không?
namespace C {
class X {};
}
namespace A {
class X {};
namespace B {
using namespace C;
X x;
}
}
Tôi đã chờ đợi loại x
là C::X
do chỉ thị using namespace
, nhưng thay vào đó cả VS2010 và trực tuyến LLVM/Clang biên dịch quyết tâm X
trong namespace B
là A::X
. Thay đổi chỉ thị sử dụng bằng tuyên bố sử dụng (using C::X
), sau đó nó sẽ giải quyết thành C::X
như mong đợi.
Tiêu chuẩn nói trên sử dụng chỉ thị [7.3.4.2]:
Một sử dụng-chỉ thị xác định rằng tên trong không gian tên được đề cử có thể được sử dụng trong phạm vi trong đó sử dụng-chỉ xuất hiện sau khi sử dụng -directive. Trong quá trình tra cứu tên không đủ tiêu chuẩn (3.4.1), các tên xuất hiện như thể chúng được khai báo trong không gian tên bao quanh gần nhất chứa cả không gian tên sử dụng và chỉ định được chỉ định.
đọc My của việc này là C::X
nên xuất hiện như thể tuyên bố trong namespace B
, hiệu quả che giấu A::X
. (Các) phần nào của tiêu chuẩn nằm sau sự không nhất quán này giữa việc sử dụng các chỉ thị và sử dụng các khai báo? Có cách nào để giấu tên từ một phạm vi bên ngoài bằng một chỉ thị sử dụng không?
Có thể đầu mối nằm trong * các tên xuất hiện như thể chúng được khai báo trong không gian tên bao quanh gần nhất chứa ** cả ** chỉ thị sử dụng và không gian tên được chỉ định *. Điều đó không phải là '::'? Và nếu vậy, sẽ không tìm thấy 'A :: X' trước (tra cứu đi từ không gian tên bên trong) ... không chắc chắn, nhưng g ++ cũng lấy 'A :: X', vì vậy nó rất * nhất quán trên các trình biên dịch. –
@David Rodríguez - dribeas: Ồ, điều đó sẽ giải thích nó ... –