Làm cách nào để tôi có thể "hủy sử dụng" một không gian tên?


86

Một trong những điểm mơ hồ của hệ thống phát triển của tôi (Codegear C ++ Builder) là một số tiêu đề được tạo tự động đòi hỏi phải có ...

using namespace xyzzy

... các câu lệnh trong đó, tác động đến mã của tôi khi tôi ít muốn hoặc ít mong đợi nhất.

Có cách nào tôi có thể hủy / ghi đè câu lệnh "using" trước đó để tránh điều này không.

Có lẽ...

unusing namespace xyzzy;

3
Bạn có thể nên mở báo cáo lỗi với hệ thống QC của họ: qc.codegear.com
Kris

2
BTW, đây là những tiêu đề được tạo tự động nào?
Kris Kumler 17/10/08

2
Một ngày nào đó C ++ sẽ có các mô-đun, và việc bao gồm mã vào mã khác sẽ có cấu trúc đóng gói tốt hơn. Cho đến lúc đó, không có một cách dễ dàng để giải quyết vấn đề này. Cân nhắc đặt mã của riêng bạn vào một không gian tên và tham chiếu đến nó theo cách đó.
Trevor Hickey

Câu trả lời:


59

Không. Nhưng có một giải pháp tiềm năng: nếu bạn đặt chỉ thị include của mình trong một không gian tên của riêng nó, như thế này ...

namespace codegear {
    #include "codegear_header.h"
} // namespace codegear

... thì ảnh hưởng của bất kỳ chỉ thị sử dụng nào trong tiêu đề đó sẽ bị vô hiệu hóa.

Điều đó có thể có vấn đề trong một số trường hợp. Đó là lý do tại sao mọi hướng dẫn về kiểu C ++ đều khuyên bạn không nên đặt chỉ thị "sử dụng không gian tên" trong tệp tiêu đề.


1
Nói chung, đây là một ý tưởng kinh khủng . Tiêu đề C ++ không dự định được đưa vào một vùng tên thay thế như được sử dụng ở đây.
Aaron

24
Cũng là một ý tưởng tồi khi đưa một chỉ thị using vào tệp tiêu đề. Điều này chỉ đơn giản là giảm nhẹ vấn đề đó.
Head Geek

4
Đặt tiêu đề trong không gian tên của riêng bạn không phải là một giải pháp vì nó thay đổi ý nghĩa của các khai báo trong thư viện đó. (-1)
Richard Corden

4
Điều đó hoàn toàn phụ thuộc vào những gì được khai báo trong tiêu đề.
Head Geek

1
Đó chính là lý do tại sao nó là hành vi không xác định.
Kris Kumler 17/10/08

56

Không, bạn không thể hủy sử dụng một không gian tên. Điều duy nhất bạn có thể làm là đặt using namespace-statement một khối để giới hạn phạm vi của nó.

Thí dụ:

{
    using namespace xyzzy;

} // stop using namespace xyzzy here

Có thể bạn có thể thay đổi mẫu được sử dụng cho các tiêu đề được tạo tự động của mình.


Bạn có thể bọc một bao gồm trong một khối như thế này không?
Eclipse

Có, điều này sẽ không xảy ra với mã được tạo tự động. Byt mybe anh ấy có thể thay đổi mẫu cho mã được tạo tự động không?
jk.

Vâng, điều này không thực sự giải quyết được vấn đề anh ấy gặp phải về tiêu đề bằng cách sử dụng không gian tên.
Kip

Thật không may, điều này là không đúng sự thật. Hãy thử điều này:
Adam

không gian tên xyzzy {const int i {using không gian tên xyzzy; } // dừng sử dụng không gian tên xyzzy tại đây
Adam

17

Bạn có thể gặp khó khăn khi sử dụng không gian tên rõ ràng do xung đột:

string x; // Doesn't work due to conflicting declarations
::string y; // use the class from the global namespace
std::string z; // use the string class from the std namespace

10

Để tham khảo trong tương lai: vì phiên bản XE có một giá trị mới mà bạn có thể # xác định để tránh gặp phải using namespace System;rắc rối trong bao gồm: DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE


Nhưng điều này dường như không hoạt động đúng. Ít nhất trong tất cả các trường hợp tôi đã thử (với BCB6). Sau đó tôi sử dụng để rơi trở lại vào thêm không gian tên rõ ràng về xung đột và - thậm chí tệ hơn - bao gồm một tiêu đề để tránh xung đột tên loại ...
Wolf

6

Làm thế nào về việc sử dụng sed, perl hoặc một số công cụ dòng lệnh khác như một phần của quá trình xây dựng của bạn để sửa đổi các tiêu đề được tạo sau khi chúng được tạo nhưng trước khi chúng được sử dụng?


1

Thử nghiệm nhanh với Visual Studio 2005 cho thấy rằng bạn có thể đặt các tiêu đề đó trong không gian tên được đặt tên của riêng bạn và sau đó là usenhững gì bạn cần từ không gian tên này (nhưng không phải usetoàn bộ không gian tên, vì nó sẽ giới thiệu không gian tên bạn muốn ẩn.


1
Điều này có thể sẽ gây ra vấn đề mang tên nếu tệp tiêu đề là khai báo cho một thư viện. Quá trình biên dịch sẽ thành công, nhưng trình liên kết sẽ không thể tìm thấy các định nghĩa, vì chúng đã được biên dịch trong một không gian tên khác.
Eclipse

-1
#include<iostream>
#include<stdio.h>
namespace namespace1 {
    int t = 10;
}
namespace namespace2 {
    int t = 20;
}
int main() {
using namespace namespace1;
    printf("%d" , t);
    printf("%d" , namespace2::t);
}

1
xin vui lòng giải thích câu trả lời của bạn!
Mazz

bạn có thể sử dụng toán tử phân giải phạm vi sử dụng một biến namespace
Narendra kumawat

3
Không giải quyết được câu hỏi
MM
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.