Trong C ++, một không gian tên bí danh là gì?


156

Một "bí danh không gian tên" trong C ++ là gì? Nó được sử dụng như thế nào?

Câu trả lời:


186

Bí danh không gian tên là một cách thuận tiện để tham chiếu đến một tên không gian tên dài bằng một tên khác, ngắn hơn.

Ví dụ: giả sử bạn muốn sử dụng các vectơ số từ uBLAS của Boost mà không cần lệnh using namespace. Nói rõ không gian tên đầy đủ mỗi lần là cồng kềnh:

boost::numeric::ublas::vector<double> v;

Thay vào đó, bạn có thể định nghĩa một bí danh cho boost::numeric::ublas- giả sử chúng tôi muốn viết tắt từ này thành ublas:

namespace ublas = boost::numeric::ublas;


ublas::vector<double> v;

7
Để có thể giải thích các downvote, SO không và sẽ không bao giờ là sự thay thế cho một cuốn sách giáo khoa C ++ tốt. Câu hỏi bạn đặt ra sẽ được trả lời bởi bất kỳ cuốn sách như vậy. Và "tính năng" SO của việc trả lời các câu hỏi của riêng bạn không nên được sử dụng để cung cấp các diễn giải của những cuốn sách đó.

24
Không có hành vi phạm tội nào chính bạn nếu nội dung đó không có trên SO ở dạng có thể truy cập. Nhưng rõ ràng, điều này được nhăn mặt?
Martin B

1
Chắc chắn có một nghi thức để trả lời câu hỏi của riêng bạn, để tránh kích thích; trong trường hợp này, điều khá rõ ràng là nó không bao giờ một câu hỏi thực sự. Ví dụ: stackoverflow.com/questions/494927/ Mạnh
Marc Gravell

6
@Martin B: Tôi không đồng ý rằng đây là một câu hỏi cấp độ đầu vào - thực tế đã có nhiều câu hỏi rõ ràng hơn được hỏi trong quá khứ với nhiều phiếu bầu. Có nói rằng, mọi người có thể cảm thấy bạn chỉ đơn giản là cố gắng để có được danh tiếng cho chính mình. Cách này là đánh dấu một hoặc cả hai câu hỏi / câu trả lời là "wiki cộng đồng". Cá nhân tôi sẽ đi với câu hỏi như bạn và trả lời như cộng đồng. Nếu câu hỏi có merrit thì bạn sẽ nhận được ROI.
Richard Corden

1
Tôi nghĩ câu hỏi quan trọng là liệu câu hỏi có thật không "- đó có phải là điều mà bạn đã được hỏi không? Có phải đó là điều mà mọi người muốn biết không? Có phải đó là điều chưa được hỏi và trả lời trên SO? Nếu bạn đọc bài đăng trên blog SO về cộng đồng R đăng và trả lời các câu hỏi ở đây, lưu ý rằng họ đã chọn các câu hỏi X hàng đầu mà cộng đồng của họ thực sự hỏi , vì vậy nó có liên quan trong thế giới thực. Lấy các đoạn ngẫu nhiên về kiến ​​thức ngôn ngữ cụ thể và đăng chúng ở đây dường như ít hữu ích hơn
jalf

7

Rất đơn giản, #define sẽ không hoạt động.

namespace Mine { class MyClass { public: int i; }; }
namespace His = Mine;
namespace Yours { class Mine: public His::MyClass { void f() { i = 1; } }; }

Biên dịch tốt. Cho phép bạn làm việc xung quanh không gian tên / xung đột tên lớp.

namespace Nope { class Oops { public: int j; }; }
#define Hmm Nope
namespace Drat { class Nope: public Hmm::Oops { void f () { j = 1; } }; }

Trên dòng cuối cùng, "Hmm: Oops" là một lỗi biên dịch. Bộ xử lý trước thay đổi nó thành Nope :: Oops, nhưng Nope đã là một tên lớp.


3
Những gì #define? Có lẽ câu trả lời của bạn đề cập đến một phiên bản trước của câu hỏi?
einpoklum

3

Thêm thông tin về chủ đề này http://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Core-C-/Stephan-T-Lavavej-Core-C-1-of-n

Đó là tất cả về việc chọn một bí danh cho một tên không gian tên looong, chẳng hạn như:

namespace SHORT = NamespaceFirst::NameSpaceNested::Meow

Sau đó, bạn có thể typedef

typedef SHORT::mytype

thay vì

typedef NamespaceFirst::NameSpaceNested::Meow::mytype

Cú pháp này chỉ hoạt động cho các không gian tên, không thể bao gồm các lớp, các loại sau namespace NAME =


3

Cũng lưu ý rằng các bí danh không gian tên và sử dụng các lệnh được giải quyết tại thời gian biên dịch, không phải thời gian chạy. (Cụ thể hơn, cả hai đều là công cụ được sử dụng để báo cho trình biên dịch biết nơi khác cần tìm khi phân giải tên, nếu nó không thể tìm thấy một ký hiệu cụ thể trong phạm vi hiện tại hoặc bất kỳ phạm vi chính nào của nó.) biên dịch:

namespace A {
    int foo;
    namespace AA {
        int bar;
    } // namespace AA
    namespace AB {
        int bar;
    } // namespace AB
} // namespace A
namespace B {
    int foo;
    namespace BA {
        int bar;
    } // namespace BA
    namespace BB {
        int bar;
    } // namespace BB
} // namespace B

bool nsChooser1, nsChooser2;
// ...

// This doesn't work.
namespace C = (nsChooser1 ? A : B);
C::foo = 3;

// Neither does this.
// (Nor would it be advisable even if it does work, as compound if-else blocks without braces are easy to inadvertently break.)
if (nsChooser1)
    if (nsChooser2)
        using namespace A::AA;
    else
        using namespace A::AB;
else
    if (nsChooser2)
        using namespace B::BA;
    else
        using namespace B::BB;

Bây giờ, một trí óc tò mò có thể nhận thấy rằng constexprcác biến cũng được sử dụng tại thời điểm biên dịch và tự hỏi liệu chúng có thể được sử dụng cùng với bí danh hoặc chỉ thị hay không. Theo hiểu biết của tôi, họ không thể, mặc dù tôi có thể sai về điều này. Nếu bạn cần làm việc với các biến có tên giống hệt nhau trong các không gian tên khác nhau và chọn giữa chúng một cách linh hoạt, bạn sẽ phải sử dụng các tham chiếu hoặc con trỏ.

// Using the above namespaces...
int& foo = (nsChooser1 ? A::foo : B::foo);

int* bar;
if (nsChooser1) {
    if (nsChooser2) {
        bar = &A::AA::bar;
    } else {
        bar = &A::AB::bar;
    }
} else {
    if (nsChooser2) {
        bar = &B::BA::bar;
    } else {
        bar = &B::BB::bar;
    }
}

Sự hữu ích của những điều trên có thể bị hạn chế, nhưng nó sẽ phục vụ mục đích.

(Lời xin lỗi của tôi cho bất kỳ lỗi đánh máy nào tôi có thể đã bỏ lỡ ở trên.)


0

Không gian tên được sử dụng để ngăn ngừa xung đột tên.

Ví dụ:

namespace foo {
    class bar {
        //define it
    };
}

namespace baz {
    class bar {
        // define it
    };
}

Bây giờ bạn có hai thanh tên lớp, hoàn toàn khác nhau và tách biệt nhờ vào không gian tên.

"Sử dụng không gian tên" mà bạn hiển thị là để bạn không phải chỉ định không gian tên để sử dụng các lớp trong không gian tên đó. tức là std :: string trở thành chuỗi.

tài nguyên của tôi: https://www.quora.com/What-is-namespace-in-C++-1

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.