2010-02-07 29 views

Trả lời

42

Kể từ khi chuẩn C++ đã được chấp nhận, thực tế tất cả các thư viện giữa các ý kiến ​​bên trong namespace std. Vì vậy, nếu bạn không muốn hội đủ điều kiện tất cả các cuộc gọi thư viện chuẩn với std::, bạn cần phải thêm chỉ thị sử dụng.

Tuy nhiên,

using namespace std; 

được coi là một thực tế xấu bởi vì bạn đang thực tế nhập khẩu toàn bộ không gian tên tiêu chuẩn, do đó mở ra nhiều khả năng xung đột tên. Chỉ nên nhập những thứ bạn đang thực sự sử dụng trong mã của mình, chẳng hạn như

using std::string; 
+14

+1 Vì là người duy nhất đề cập đến nó, nó cau mày. – GManNickG

23

Không có gì, đó là một cách viết tắt để tránh tiền tố tất cả mọi thứ trong namespace rằng với std ::

+11

Và cũng được coi là thực hành kém. – GManNickG

+2

thực hành kém của nó nếu bạn làm điều đó không gian tên chung: D –

+7

@GMan, @Hassan: Thật tuyệt khi sử dụng nó trong tệp triển khai và nguy hiểm trong tệp tiêu đề. Tại sao mọi người cứ nói "thực hành kém"? Tôi sẽ không muốn làm việc trên mã mà tôi phải gõ 'std ::' trên khắp nơi, cũng giống như tôi không muốn nhập khẩu bất kỳ không gian tên ngầm nào với 'using namespace some_tools; ' – Potatoswatter

5

Khả năng tham khảo cho các thành viên trong không gian tên std mà không cần phải tham khảo std::member một cách rõ ràng. Ví dụ:

#include <iostream> 
using namespace std; 

... 
cout << "Hi" << endl; 

vs

#include <iostream> 

... 
std::cout << "Hi" << std::endl; 
3

Trước hết, điều này là không cần thiết trong C - C không có không gian tên. Trong C++, bất cứ điều gì trong không gian tên std bao gồm hầu hết các thư viện chuẩn. Nếu bạn không làm điều này bạn phải truy cập vào các thành viên của không gian tên một cách rõ ràng như sau:

std::cout << "I am accessing stdout" << std::endl; 
0

Tất cả các tập tin trong thư viện chuẩn C++ khai báo tất cả các đơn vị của mình trong namespace std.
ví dụ: Để sử dụng cin,cout quy định tại iostream

Alternatives:

using std::cout; 
using std::endl; 
cout << "Hello" << endl;
std::cout << "Hello" << std::endl;

0

Được sử dụng bất cứ khi nào bạn đang sử dụng thứ gì đó được khai báo trong không gian tên. Thư viện chuẩn C++ được khai báo trong không gian tên std. Vì vậy, bạn phải làm

using namespace std; 

trừ khi bạn muốn xác định không gian tên khi gọi chức năng trong không gian tên khác, như vậy:

std::cout << "cout is declared within the namespace std"; 

Bạn có thể đọc thêm về nó tại http://www.cplusplus.com/doc/tutorial/namespaces/.

3

Thứ nhất, chỉ thị using không bao giờ được yêu cầu trong C vì C không hỗ trợ không gian tên nào cả.

Chỉ thị using không bao giờ thực sự cần trong C++ từ bất kỳ vật phẩm tìm thấy trong không gian tên có thể được truy cập trực tiếp bằng cách đặt trước chúng với std:: để thay thế. Vì vậy, ví dụ:

using namespace std; 
string myString; 

tương đương với:

std::string myString; 

hay không bạn chọn để sử dụng nó là một vấn đề ưu tiên, nhưng phơi bày toàn bộ std namespace để tiết kiệm một vài tổ hợp phím thường được coi là hình thức xấu. Một phương pháp thay thế mà chỉ thấy nhiều mặt hàng đặc biệt trong không gian tên như sau:

using std::string; 
string myString; 

này cho phép bạn để lộ chỉ mục trong namespace std mà bạn đặc biệt cần, mà không có nguy cơ vô tình để lộ một cái gì đó bạn không dự định.

0

Bạn không bao giờ phải khai báo bằng cách sử dụng không gian tên std; sử dụng nó là là thói quen xấu và bạn nên sử dụng std :: nếu bạn không muốn gõ std :: luôn bạn có thể làm một cái gì đó như thế này trong một số trường hợp:

using std::cout; 

Bằng cách sử dụng std :: bạn cũng có thể cho biết phần nào của chương trình của bạn sử dụng thư viện chuẩn và thư viện nào không. Điều quan trọng hơn nữa là có thể có xung đột với các chức năng khác được đưa vào.

Rgds Layne

+2

Nó chỉ là thực hành xấu trong không gian tên chung trong các tệp tiêu đề. Trong các tập tin thực hiện nó thường là một ý tưởng tốt. Lưu thao tác nhập không liên quan - trình chỉnh sửa của bạn sẽ thực hiện việc nhập cho bạn.Nó tốt vì nó làm cho mã dễ đọc hơn là có 'std ::' ở mọi nơi, và dễ bảo trì hơn là có ba mươi dòng 'sử dụng std :: whatever;' ở đầu mỗi tập tin. – Porculus

5

Bạn nên chắc chắn không phải nói:

using namespace std; 

trong tiêu đề của bạn C++, bởi vì đó đánh bại toàn bộ điểm của việc sử dụng không gian tên (làm điều đó sẽ tạo nên "ô nhiễm không gian tên"). Một số tài nguyên hữu ích về vấn đề này như sau:

1) stackoverflow thread trên Standard convention for using “std”

2) một bài viết của Herb Sutter trên Migrating to Namespaces

3) FAQ 27.5 từ Marshall Cline của C++ Faq lite.

1

Không gian tên là cách gói mã để tránh nhầm lẫn và tên không xung đột. Ví dụ:

file common1.h:

namespace intutils 
{ 
    int addNumbers(int a, int b) 
    { 
     return a + b; 
    } 
} 

tập tin Cách sử dụng:

#include "common1.h"  
int main() 
{ 
    int five = 0; 
    five = addNumbers(2, 3); // Will fail to compile since the function is in a different namespace. 
    five = intutils::addNumbers(2, 3); // Will compile since you have made explicit which namespace the function is contained within. 

    using namespace intutils; 
    five = addNumbers(2, 3); // Will compile because the previous line tells the compiler that if in doubt it should check the "intutils" namespace. 
} 

Vì vậy, khi bạn viết using namespace std tất cả các bạn đang làm là nói cho trình biên dịch rằng nếu nghi ngờ nó sẽ giống trong không gian tên std cho các chức năng, v.v., mà nó không thể tìm thấy định nghĩa cho. Điều này thường được sử dụng trong ví dụ (và sản xuất) mã đơn giản chỉ vì nó làm cho gõ chức năng phổ biến, vv như cout là nhanh hơn so với việc phải hoàn toàn đủ điều kiện mỗi một là std::cout.

7

Về mặt kỹ thuật, bạn có thể được yêu cầu sử dụng sử dụng (cho toàn bộ không gian tên hoặc tên riêng lẻ) để có thể sử dụng Tra cứu phụ thuộc đối số.

Cân nhắc hai chức năng sau sử dụng swap().

#include <iostream> 
#include <algorithm> 

namespace zzz 
{ 
    struct X {}; 


void swap(zzz::X&, zzz::X&) 
{ 
    std::cout << "Swapping X\n"; 
} 
} 

template <class T> 
void dumb_swap(T& a, T& b) 
{ 
    std::cout << "dumb_swap\n"; 
    std::swap(a, b); 
} 

template <class T> 
void smart_swap(T& a, T& b) 
{ 
    std::cout << "smart_swap\n"; 
    using std::swap; 
    swap(a, b); 
} 

int main() 
{ 
    zzz::X a, b; 
    dumb_swap(a, b); 
    smart_swap(a, b); 

    int i, j; 
    dumb_swap(i, j); 
    smart_swap(i, j); 
} 

dumb_swap luôn gọi std::swap - mặc dù chúng ta thà thích sử dụng zzz::swap cho zzz::X đối tượng.

smart_swap làm std::swap có thể nhìn thấy như một sự lựa chọn mùa thu lại (ví dụ khi gọi với ints), nhưng vì nó không đủ điều kiện đầy đủ tên, zzz::swap sẽ được sử dụng thông qua ADL cho zzz::X.


Về chủ quan, những gì buộc tôi phải sử dụng using namespace std; được viết mã có sử dụng tất cả các loại đối tượng chức năng tiêu chuẩn vv

//copy numbers larger than 1 from stdin to stdout 
remove_copy_if(
    std::istream_iterator<int>(std::cin), std::istream_iterator<int>(), 
    std::ostream_iterator<int>(std::cout, "\n"), 
    std::bind2nd(std::less_equal<int>(), 0) 
); 

IMO, trong mã như std:: này chỉ làm cho tiếng ồn dòng.

Tôi sẽ không tìm thấy using namespace std; một tội ác ghê tởm trong những trường hợp như vậy, nếu nó được sử dụng trong tệp triển khai (nhưng nó thậm chí có thể bị giới hạn phạm vi chức năng, như trong ví dụ trao đổi).

Chắc chắn không đặt câu lệnh sử dụng trong tệp tiêu đề. Lý do là điều này gây ô nhiễm không gian tên cho các tiêu đề khác, có thể được bao gồm sau phần đầu phạm vi, có khả năng dẫn đến lỗi trong các tiêu đề khác mà có thể không nằm trong tầm kiểm soát của bạn. (Nó cũng cho biết thêm yếu tố bất ngờ: những người bao gồm cả tệp có thể không mong đợi tất cả các loại tên được hiển thị.)

0

Không có gì yêu cầu bạn phải làm - trừ khi bạn là người triển khai Thư viện chuẩn C++ và bạn muốn tránh trùng lặp mã khi khai báo tệp tiêu đề ở cả kiểu "mới" và "cũ":

// cstdio 
namespace std 
{ 
    // ... 
    int printf(const char* ...); 
    // ... 
} 

.

// stdio.h 
#include <cstdio> 
using namespace std; 

Vâng, tất nhiên ví dụ là hơi giả tạo (bạn tốt như nhau có thể sử dụng đơn giản <stdio.h> và đặt nó tất cả trong std trong <cstdio>), nhưng Bjarne Stroustrup cho thấy ví dụ này trong mình.

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