2010-02-25 51 views
5

Trong thư viện chuẩn, tôi thấy rằng không gian tên std được khai báo là macro.Khai báo vùng tên là macro - C++

#define _STD_BEGIN namespace std { 
#define _STD_END  } 
  1. Đây có phải là cách hay nhất khi sử dụng không gian tên?
  2. Macro được khai báo trong Microsoft Visual Studio 9.0\VC\include\yvals.h. Nhưng tôi không thể tìm thấy các tập tin STL bao gồm cả điều này. Nếu nó không được bao gồm, làm thế nào nó có thể được sử dụng?

Mọi suy nghĩ ..?

Trả lời

6

Có lẽ không phải là phương pháp hay nhất vì có thể khó đọc so với tuyên bố vanilla namespace. Điều đó nói rằng, hãy nhớ rằng các quy tắc không phải lúc nào cũng áp dụng phổ biến và tôi chắc chắn có một số trường hợp macro có thể làm sạch mọi thứ một cách đáng kể.

"Nhưng tôi không thể tìm thấy tệp STL bao gồm điều này. Nếu nó không được bao gồm, làm thế nào nó có thể được sử dụng?".

Tất cả các tệp sử dụng macro này bao gồm yvals.h bằng cách nào đó. Ví dụ: <vector> bao gồm, <memory>, bao gồm <iterator>, bao gồm <xutility>, bao gồm <climits>, bao gồm <yvals.h>. Chuỗi có thể sâu, nhưng nó không bao gồm nó một số điểm.

Và tôi muốn làm rõ, điều này chỉ áp dụng cho việc triển khai cụ thể thư viện chuẩn này; điều này là không có cách nào tiêu chuẩn hóa.

+0

+1 để được giải thích tốt. Ước gì tôi có thể phù hợp! –

+0

Trong C++ 11 trở lên, điều này có thể rất hữu ích trong việc phiên bản thư viện của bạn với [inline namespaces] (http://en.cppreference.com/w/cpp/language/namespace#Inline_namespaces). Về cơ bản, macro của bạn sẽ thay đổi tên của không gian tên nội tuyến bất cứ khi nào khả năng tương thích ABI bị hỏng. –

3
  1. Nói chung không. Macro có thể được sử dụng tại thời điểm không gian tên không được thực hiện bởi một số trình biên dịch hoặc để tương thích với nền tảng cụ thể.
  2. Không có ý tưởng. Tệp có thể được bao gồm bởi một số tệp khác được đưa vào tệp STL.
+0

Cảm ơn. Tôi đã kiểm tra và không thể tìm thấy một số tệp khác bao gồm tệp này. –

1

Tôi tưởng tượng lý do duy nhất để làm điều này là nếu bạn muốn dễ dàng thay đổi không gian tên được ứng dụng/thư viện của bạn sử dụng hoặc vô hiệu hóa các không gian tên vì lý do tương thích.

1

Một cách tiếp cận mà tôi đã thấy trong một thư viện mà tôi sử dụng gần đây là:

BEGIN_NAMESPACE_XXX() 

nơi XXX là số cấp namespace ví dụ:

BEGIN_NAMESPACE_3(ns1, ns1, ns3) 

sẽ mất ba lập luận và mở rộng sang

namespace ns1 { 
    namespace ns2 { 
     namespace ns2 { 

và kết hợp END_NAMESPACE_3 sẽ mở rộng thành

 } 
    } 
} 

(Tôi đã thêm các dòng mới và thụt đầu dòng cho chỉ vì lợi ích rõ ràng của)

0

tôi có thể thấy làm điều này cho các thư viện C được bao gồm trong C++ bằng cách tham chiếu (ví dụ., Tiêu đề mà C gọi string.h và C++ gọi cstring). Trong trường hợp đó, định nghĩa macro sẽ phụ thuộc vào một số #ifdef _c_plus_plus.

Tôi sẽ không làm điều đó nói chung. Tôi không thể nghĩ rằng bất kỳ trình biên dịch có giá trị sử dụng không hỗ trợ không gian tên, ngoại lệ, mẫu hoặc các tính năng C++ hiện đại khác (hiện đại là dấu ngoặc kép vì các tính năng này được thêm vào giữa đến cuối những năm 90). Trong thực tế, theo định nghĩa của tôi, các trình biên dịch chỉ có giá trị sử dụng nếu chúng cung cấp hỗ trợ tốt cho ngôn ngữ tương ứng của chúng. Đây không phải là vấn đề ngôn ngữ; đó là một trường hợp đơn giản của "nếu tôi chọn ngôn ngữ X, tôi muốn sử dụng nó như nó tồn tại ngày hôm nay, không phải như nó tồn tại một hoặc hai thập kỷ trước." Tôi chưa bao giờ hiểu tại sao một số dự án dành thời gian cố gắng để hỗ trợ các trình biên dịch pre-ANSI C, ví dụ.

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