Đầu tiên, một số thuật ngữ:
- using-khai báo :
using std::vector;
- using-chỉ thị :
using namespace std;
Tôi nghĩ rằng việc sử dụng các chỉ thị using cũng được, miễn là chúng không được sử dụng ở phạm vi toàn cục trong một tệp tiêu đề. Vì vậy, có
using namespace std;
trong tệp .cpp của bạn không thực sự là một vấn đề và nếu nó xảy ra, nó hoàn toàn nằm trong tầm kiểm soát của bạn (và thậm chí nó có thể được xác định phạm vi đến các khối cụ thể nếu muốn). Tôi không thấy lý do cụ thể nào để làm lộn xộn mã với một loạt các std::
vòng loại - nó chỉ trở thành một đống nhiễu trực quan. Tuy nhiên, nếu bạn không sử dụng toàn bộ tên từ std
không gian tên trong mã của mình, tôi cũng không thấy vấn đề gì với việc loại bỏ chỉ thị. Đó là một sự phản phục - nếu chỉ thị không cần thiết, thì không cần sử dụng nó.
Tương tự như vậy, nếu bạn có thể sử dụng một số khai báo bằng cách sử dụng (thay vì sử dụng chỉ thị ) cho các kiểu cụ thể trong std
không gian tên, thì không có lý do gì bạn không nên chỉ đưa những tên đặc biệt đó vào không gian tên hiện tại. Tương tự như vậy, tôi nghĩ sẽ thật điên rồ và rắc rối trong việc ghi sổ kế toán khi có 25 hoặc 30 khai báo sử dụng khi một chỉ thị sử dụng duy nhất cũng thực hiện thủ thuật.
Cũng nên nhớ rằng đôi khi bạn phải sử dụng khai báo using. Tham khảo "Mục 25: Xem xét hỗ trợ cho một giao dịch hoán đổi không ném" từ C ++ hiệu quả, Phiên bản thứ ba. Để có một hàm mẫu, chung chung sử dụng phương pháp hoán đổi 'tốt nhất' cho một kiểu tham số, bạn cần sử dụng tra cứu phụ thuộc vào khai báo và đối số (còn gọi là tra cứu ADL hoặc Koenig):
template< typename T >
void foo( T& x, T& y)
{
using std::swap; // makes std::swap available in this function
// do stuff...
swap( x, y); // will use a T-specific swap() if it exists,
// otherwise will use std::swap<T>()
// ...
}
Tôi nghĩ chúng ta nên xem xét các thành ngữ phổ biến cho các ngôn ngữ khác nhau sử dụng không gian tên đáng kể. Ví dụ, Java và C # sử dụng không gian tên ở một mức độ lớn (được cho là nhiều hơn C ++). Cách phổ biến nhất mà tên trong không gian tên được sử dụng trong các ngôn ngữ đó là đưa chúng vào phạm vi hiện tại hàng loạt với tương đương với chỉ thị sử dụng. Điều này không gây ra các vấn đề trên diện rộng và một vài lần vấn đề được xử lý trên cơ sở 'ngoại lệ' bằng cách xử lý các tên được đề cập thông qua các tên đủ điều kiện hoặc bằng bí danh - giống như có thể được thực hiện trong C ++.
Herb Sutter và Andrei Alexandrescu có điều này để nói trong "Mục 59: Không viết sử dụng không gian tên trong tệp tiêu đề hoặc trước #include" của cuốn sách của họ, Tiêu chuẩn mã hóa C ++: 101 Quy tắc, Nguyên tắc và Thực tiễn Tốt nhất:
Tóm lại: Bạn có thể và nên sử dụng không gian tên bằng cách sử dụng các khai báo và chỉ thị một cách tự do trong các tệp triển khai của mình sau #include
các lệnh và cảm thấy hài lòng về nó. Mặc dù có nhiều lần khẳng định ngược lại, không gian tên sử dụng các khai báo và chỉ thị không phải là xấu và chúng không đánh bại mục đích của không gian tên. Đúng hơn, chúng là thứ làm cho không gian tên có thể sử dụng được.
Stroupstrup thường được trích dẫn câu nói, "Đừng làm ô nhiễm không gian tên chung", trong "Ngôn ngữ lập trình C ++, phiên bản thứ ba". Trên thực tế, anh ta nói điều đó (C.14 [15]), nhưng đề cập đến chương C.10.1, nơi anh ta nói:
Một khai báo using thêm tên vào một phạm vi cục bộ. Một chỉ thị sử dụng không; nó chỉ hiển thị các tên có thể truy cập được trong phạm vi mà chúng đã được khai báo. Ví dụ:
namespaceX {
int i , j , k ;
}
int k ;
void f1()
{
int i = 0 ;
using namespaceX ; // make names from X accessible
i++; // local i
j++; // X::j
k++; // error: X::k or global k ?
::k ++; // the global k
X::k ++; // X’s k
}
void f2()
{
int i = 0 ;
using X::i ; // error: i declared twice in f2()
using X::j ;
using X::k ; // hides global k
i++;
j++; // X::j
k++; // X::k
}
Tên được khai báo cục bộ (được khai báo bởi một khai báo thông thường hoặc bởi một khai báo sử dụng) ẩn các khai báo phi địa phương của cùng một tên và bất kỳ sự quá tải bất hợp pháp nào của tên đều được phát hiện tại điểm khai báo.
Lưu ý lỗi không rõ ràng cho k++
in
f1()
. Tên chung không được ưu tiên so với tên từ không gian tên có thể truy cập được trong phạm vi toàn cầu. Điều này cung cấp sự bảo vệ đáng kể chống lại các cuộc đụng độ tên ngẫu nhiên, và - quan trọng - đảm bảo rằng không có lợi thế nào đạt được từ việc làm ô nhiễm không gian tên toàn cầu.
Khi các thư viện khai báo nhiều tên được làm cho có thể truy cập được thông qua các chỉ thị sử dụng, thì đó là một lợi thế đáng kể mà các xung đột của các tên không sử dụng không bị coi là lỗi.
...
Tôi hy vọng sẽ thấy việc sử dụng tên chung trong các chương trình mới sử dụng không gian tên giảm hẳn so với các chương trình C và C ++ truyền thống. Các quy tắc cho không gian tên được thiết kế đặc biệt để không mang lại lợi ích cho người dùng tên toàn cầu '' lười biếng '' so với người cẩn thận không làm ô nhiễm phạm vi toàn cầu.
Và làm thế nào một người có lợi thế giống như một 'người lười biếng của tên toàn cầu'? Bằng cách tận dụng chỉ thị using, lệnh này làm cho các tên trong vùng tên có sẵn cho phạm vi hiện tại một cách an toàn .
Lưu ý rằng có một sự khác biệt - các tên trong std
không gian tên được tạo sẵn cho một phạm vi với việc sử dụng thích hợp chỉ thị sử dụng (bằng cách đặt chỉ thị sau dấu #includes
) sẽ không gây ô nhiễm không gian tên chung. Nó chỉ làm cho những tên đó có sẵn một cách dễ dàng và với sự bảo vệ liên tục chống lại các cuộc đụng độ.