2016-05-28 16 views
39

Như được thảo luận tại Why is nullptr_t not a keyword, tốt hơn là tránh giới thiệu từ khóa mới vì chúng có thể phá vỡ tính tương thích ngược.Nếu nullptr_t không phải là một từ khóa, tại sao char16_t và char32_t?

Tại sao sau đó là char16_tchar32_t từ khóa, khi chúng cũng có thể được xác định như vậy?

namespace std { 
    typedef decltype(u'q') char16_t; 
    typedef decltype(U'q') char32_t; 
} 
+1

Đó là mới với tôi đây không phải là typedefs nữa. Bạn đã nhận được yêu cầu đó từ đâu? –

+2

@ πάνταῥεῖ Chúng được liệt kê dưới dạng từ khóa trong tiêu chuẩn. – Brian

+0

@ πάνταῥεῖ: C++ 11 cho biết chúng là từ khóa. (§2.12) – cHao

Trả lời

22

The proposal itself giải thích tại sao: để cho phép quá tải với các loại cơ bản của uint_least16_tuint_least32_t. Nếu họ là typedef, điều này sẽ không thể thực hiện được.

Xác định char16_t là một loại mới riêng biệt, có cùng kích thước và đại diện như uint_least16_t. Tương tự, hãy xác định char32_t là một loại mới riêng biệt, có cùng kích thước và biểu diễn như uint_least32_t.

[N1040 định nghĩa char16_tchar32_t như typedefs để uint_least16_tuint_least32_t, mà làm cho quá tải bằng các ký tự không thể.]

Đối với lý do tại sao họ không phải là trong không gian tên std, đây là để tương thích với các đề xuất C ban đầu. C++ cấm các định nghĩa C xuất hiện trong phiên bản riêng của mình <cuchar>

[c.strings]/3

Các tiêu đề sẽ không xác định các loại char16_t, char32_t, và wchar_t (2.11).

Các loại sau đó sẽ cần phải được typedefs toàn cầu, có thể mang theo thiết lập riêng của mình về các vấn đề như

typedef decltype(u'q') char16_t; 

namespace foo { 
    typedef int char16_t; 
} 

Lý do cho std::nullptr_t không phải là một từ khóa có thể được tìm thấy trong các câu hỏi mà bạn liên kết

Chúng tôi không hy vọng sẽ thấy nhiều việc sử dụng trực tiếp nullptr_t trong các chương trình thực.

làm nullptr_t ngoại lệ thực sự tại đây.

+5

Cách tiếp cận typedef tôi đề xuất trong câu hỏi tránh lỗ hổng này: họ có thể là các kiểu riêng biệt nhưng vẫn là typedef, giống như 'decltype (nullptr)'. – Brian

+0

@Brian Tôi đã thêm một số suy nghĩ khác. – user657267

1

Bởi vì mã nghịch ngợm như thế này:

typedef uint16_t char16_t; 

extern char * strndup16to8 (const char16_t* s, size_t n); 
extern size_t strnlen16to8 (const char16_t* s, size_t n); 

Chắc chắn, các tồn tại của C++ 11 trình biên dịch biết không loại trừ sự tồn tại của C++ 03 thư viện hoặc rất nhiều các hệ thống hoặc người sử dụng sử dụng các trình biên dịch/thư viện C++ 03.

Nếu bạn may mắn, họ sẽ làm điều này:

#if __STDC_VERSION__ < 201112L && __cplusplus < 201103L 
    typedef uint16_t char16_t; 
#endif 
+2

Làm thế nào để thay đổi chúng từ typedefs giải quyết hành vi đó? –

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