2012-01-05 27 views
7

Ít hay ít tiêu đề gợi ý. Trong khi tôi là not yet using C++0x Tôi muốn chuẩn bị sẵn sàng khi điều đó xảy ra, và tôi cũng muốn giảm số lượng mã tôi phải viết lại để sử dụng một số cơ sở của nó. Bằng cách đó tôi có thể nhận được sự tương thích ngược và chuyển tiếp trong một lần."Quay lại" nullptr tới C++ - các chương trình pre-C++ 0x

Một trong những điều thú vị nhất mà tôi đã tìm thấy là nullptr, mà tôi đã sử dụng thường xuyên hơn gần đây.

Sau khi kiểm tra "Giải pháp chính thức" và Meyer's suggestion, tôi quyết định sử dụng điều này trong cả C++ và các chương trình C++ 0x trong tương lai. Phần thứ hai là đơn giản - là một từ khóa, nullptr sẽ đơn giản được hỗ trợ. Nhưng phần đầu tiên khiến tôi cảm thấy khó chịu.

Các Meyers chức năng đề nghị như thế này:

class nullptr_t { // ← this is my issue 
    // definition of nullptr_t 
} nullptr = { }; 

Vấn đề với đề nghị đó là nó tuyên bố kiểu được khai báo là std::nullptr_t theo yêu cầu của C++ 0x. Điều này có nghĩa là để giải quyết vấn đề "cảm thấy bản địa", nó phải được thực hiện bằng cách mở lại không gian tên std:: để thêm một loại. Tôi hiểu được việc làm bất hợp pháp trong chương trình C++ (không giống như thêm chuyên môn rõ ràng là cau mày-và-để-đi-với-một-cảnh báo).

Tôi muốn sử dụng nullptr trong cách thoải mái cách hợp pháp trong chương trình C++. Một lựa chọn Tôi đã nghĩ đến đã tuyên bố các loại trong namespace khác và sau đó mang nó trong việc sử dụng using:

namespace mylibrary { 
class nullptr_t { 
    .... 
} nullptr = { }; 
// end namespace 
} 

// These would have to go in the header file. 
using mylibrary::nullptr; 
using mylibrary::nullptr_t; // apparently this is necessary as well? 

này sẽ được cách chính xác để làm cho nó hoạt động? Nó sẽ buộc các chỉ thị using, cũng buộc chỉ thị cụ thể của các chỉ thị #include. Tôi có quyền mong đợi rằng không có mã C++ 0x trước nào sẽ yêu cầu loại nullptr_t với không gian tên (ví dụ như một loại đối số hàm)? Nó sẽ thực sự làm việc "cảm thấy bản địa" nếu nó được thực hiện theo cách này?


Là phụ lục, bạn có muốn thử và quay lại một số tiện ích C++ 0x để C++ có khả năng tương thích và mã hóa tốt hơn không? Trong khi chờ đợi, tôi đã tích hợp giải pháp này và những giải pháp khác mà tôi đang làm việc trên in a piece of software to be released.

Trả lời

0

Lý do chính bạn không được phép thêm mọi thứ vào namespace std là vì vậy bạn không gây rối những thứ đã có sẵn. Điều này có thể dễ dàng được thực hiện. Cái mà tôi đã tìm thấy trong quá khứ là nhiều định nghĩa cho các toán tử đầu ra cho các thùng chứa được khởi tạo với một kiểu dựng sẵn như std::vector<int>. Tuy nhiên, nullptr_t không được xác định trong không gian tên này và thêm typedef phải khá vô hại. Tức là, tôi sẽ xác định nullptr_t trong một không gian tên khác với namespace std và sau đó thêm typedef cho nullptr_t đến namespace std. Biến số nullptr cần được khai báo ở phạm vi toàn cầu vì nó được sử dụng không đủ tiêu chuẩn trong C++ 2011.

Cho dù loại std::nullptr_t là cần thiết tùy thuộc vào việc bạn quan tâm đến việc thêm chữ ký bằng cách sử dụng loại này hay không. Ví dụ: std::shared_ptr<T> có thể được so sánh với nullptr. Đối với điều này, nó là cần thiết để thêm quá tải thích hợp đề cập đến loại std::nullptr_t (hoặc sử dụng một số tên khác cho loại này).

+0

Tôi luôn nghĩ rằng lý do bạn không thể thêm thứ vào 'namespace std' không phải là do bạn không làm hỏng những thứ ở đó, nhưng để mã của bạn biên dịch trên nhiều trình biên dịch (người có thể sử dụng tên bạn đã chọn), và vì vậy nó tiếp tục biên dịch khi tiêu chuẩn thêm công cụ vào không gian tên 'std'. –

+0

(1) Tôi tin rằng không gian tên được dành riêng cho việc triển khai_ vì vậy, ' 'được phép làm bất cứ điều gì nó muốn trong' std'. (2) Điều này là để mã của tôi _only_ biên dịch với một thư viện chuẩn, nó có thể biên dịch với _all các triển khai phù hợp khác của thư viện chuẩn. (3) Tất cả các tên kết thúc bằng '_t' được dành riêng cho việc thực hiện trong C++ 03. –

+0

Từ những gì tôi hiểu, quy tắc "gạch dưới" tồn tại một cách chính xác để "triển khai" sử dụng các tên đó một cách tự do (chỉ cần kiểm tra bất kỳ bản sao nào của '', ngoài các tên được cung cấp bởi Chuẩn (chẳng hạn như 'cin',' cout' không có tên nào khác được bảo lưu ngay cả trong không gian tên std, tại thời điểm đó, một 'typedef' không thể làm hại khả năng tương thích về phía trước so với khai báo thực tế, ngoại trừ nó không cho phép chúng ta thêm các công cụ _too much_ (như" namespace namespace ") –

2

Trừ khi bạn có thể nghĩ ra một lý do bạn cần phải khai báo một đối tượng loại nullptr_t (Tôi không thể), tôi sẽ giấu kiểu đi và đưa nullptr trong không gian tên toàn cầu để bắt chước một từ khóa càng sát càng tốt :

namespace mylibrary 
{ 
    class nullptr_t 
    { 
     .... 
    }; 
} 

mylibrary::nullptr_t nullptr = { }; 
+1

Có, ẩn loại bỏ đi là những gì tôi muốn làm. Tôi quan tâm nhiều hơn nếu có bất kỳ lý do nào đó tại sao một người nào đó sẽ cần sử dụng * type * 'nullptr_t' cho bất kỳ thứ gì không thể thực hiện bằng cách đơn giản truyền' nullptr' hoặc một kiểu con trỏ. –

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