2010-03-10 10 views
46

Tôi thấy rằng nullptr được triển khai trong Visual Studio 2010. Tôi thích khái niệm và muốn bắt đầu sử dụng nó càng sớm càng tốt; tuy nhiên GCC vẫn chưa hỗ trợ. Mã của tôi cần chạy trên cả hai (nhưng không phải biên dịch với các trình biên dịch khác).Có thể nullptr được mô phỏng trong gcc không?

Có cách nào để "mô phỏng" không? Một cái gì đó như:

#define nullptr NULL 

(Đó rõ ràng là sẽ không làm việc tốt ở tất cả, nó chỉ là để hiển thị những gì tôi có ý nghĩa.)

Trả lời

60

The Official proposal có một cách giải quyết -

const      // this is a const object... 
class { 
public: 
    template<class T>   // convertible to any type 
    operator T*() const  // of null non-member 
    { return 0; }   // pointer... 
    template<class C, class T> // or any type of null 
    operator T C::*() const // member pointer... 
    { return 0; } 
private: 
    void operator&() const; // whose address can't be taken 
} nullptr = {};    // and whose name is nullptr 
+3

Cảm ơn. Bạn cũng biết nếu có một cách để phát hiện nếu 'nullptr' được thực hiện, mà không dựa vào phiên bản của __cplusplus (bởi vì về mặt kỹ thuật tôi đang sử dụng C++ 0x, và nullptr không có) – nuzz

+10

@nuzz: Sau đó bạn aren không sử dụng C++ 0x. :) – Bill

+3

Vâng, tôi đang sử dụng một phần của C++ 0x;) – nuzz

8

Dường như gcc hỗ trợ nullptr là 4.6.

6

Ngoài ra, gcc (trên thực tế g ++) đã có phần mở rộng __null trong nhiều năm. Điều này được tính là kinh nghiệm triển khai ngành khi đề xuất nullptr xuất hiện.

Phần mở rộng __null có thể phát hiện các trường hợp đặc biệt và cảnh báo về chúng như vô tình truyền NULL đến tham số bool, khi nó được dự định truyền cho tham số con trỏ (thay đổi được thực hiện cho hàm, quên điều chỉnh phía cuộc gọi) .

Tất nhiên đây không phải là di động. Các giải pháp mẫu ở trên là xách tay.

+0

__null chỉ là những gì NULL được định nghĩa cho gcc, mà nó sử dụng để đưa ra cảnh báo. Nó không khác với sử dụng NULL, và không có cùng ngữ nghĩa như nullptr. – rdb

4

Có vẻ như gcc 4.6.1 (Ubuntu 11.11 oneiric), nullptr đã được thêm vào.

Một cách nhanh chóng, đệ quy sed tìm và thay thế vào hpp/file cpp của tôi làm việc tốt cho tôi:

find . -name "*.[hc]pp" | xargs sed -i 's/NULL/nullptr/g' 
2

Nó rất có thể là bạn quên -std = C++ 0x. Phiên bản gw của tôi là 4.6.1/4.7.1, cả hai đều hỗ trợ nullptr tốt.

Theo mô tả trong "Thư viện chuẩn C++, hướng dẫn và tham chiếu, thứ 2", nullptr là từ khóa, có thể tự động chuyển đổi thành từng loại con trỏ chứ không phải kiểu số nguyên, điều này khắc phục nhược điểm của NULL. chức năng quá tải sau đây: void f (int); void f (void *);

f (NULL); // Không rõ ràng f (nullptr); // OK

thử nghiệm tính năng này trong VC2010 cho thấy rằng những cuộc xung đột tài liệu MSDN với trình biên dịch thực tế, tài liệu cho biết:

Từ khóa nullptr không phải là một loại và không được hỗ trợ để sử dụng với:

sizeof

typeid

ném nullptr

trên thực tế trong VC2010, tất cả các nhà điều hành/nhanh trên ion là hợp pháp. sizeof (nullptr) kết quả 4. typeid.name() kết quả std :: nullptr_t, và ném nullptr có thể bị bắt bởi "const void *" và "void *" (và các kiểu con trỏ khác).

Trong khi gcc (4.7.1) trông cứng nhắc hơn về nullptr, ném nullptr không thể bị bắt bởi "void *", có thể bị bắt bởi '...'

+3

Không, rất có thể câu hỏi đã được 2 tuổi, từ thời điểm gcc không hỗ trợ 'nullptr'. Nhưng các câu trả lời nói rằng 4,6 hỗ trợ nó thực sự là 1,5 tuổi, quá, đã. Vì vậy, tôi đoán "câu trả lời" của bạn hoàn toàn lỗi thời. –