2011-08-05 25 views
16

Trong article on defining your own extensions to ::std::error_code này tác giả khuyến cáo mã này:Bạn có thể tiêm chuyên môn vào không gian tên std không?

namespace std 
{ 
    template <> 
    struct is_error_code_enum<http_error> 
    : public true_type {}; 
} 

để cho phép chuyển đổi từ hằng số lỗi của riêng bạn để loại lỗi hệ thống.

Điều này có hợp lý không? Nó luôn khiến tôi lo lắng khi đặt mọi thứ vào không gian tên std. Có cách nào tốt hơn để hoàn thành mục tiêu không? Không phải tất cả những điều đó, có một phần của tiêu chuẩn nói rằng điều này luôn luôn là OK để làm gì?

Trả lời

23

Yep, chuyên môn (đối với loại do người dùng xác định) của loại std hiện tại là chỉ điều bạn được phép đặt trong không gian tên std, miễn là chuyên môn đáp ứng các yêu cầu cho mẫu ban đầu.

Xem 17.6.4.2.1 trong bản nháp C++ 0x.

Loại mới, quá tải chức năng và bất kỳ thứ gì khác, tất nhiên, đều bị cấm. Nhưng chuyên môn của các mẫu hiện có được cho phép.

+1

Bạn có câu trả lời tốt hơn, nhưng @ Steve314 bao gồm các chi tiết quan trọng mà trong một số trường hợp, bạn hoàn toàn phải làm điều này. Tôi có thể sẽ chờ đợi một vài giờ (chỉ trên nguyên tắc chung) và sau đó có lẽ chấp nhận điều này. – Omnifarious

8

Đây không chỉ là OK - điều cần thiết trong một số trường hợp. Những gì bạn không nên làm là định nghĩa các hàm/lớp/mẫu hoàn toàn mới trong std.

std::swap nói riêng là điều phổ biến và đơn giản để chuyên. Một số lớp cần phải làm điều này để cho phép hoán đổi hiệu quả, về cơ bản trao đổi các tham chiếu riêng tư để trao đổi nội bộ thay vì sử dụng thực thi tạm thời và chỉ định mặc định.

EDIT

Các bình luận bằng ildjarn đề cập ADL - Argument Dependent name Lookup. Trang Wikipedia cụ thể đề cập đến std::swap trong phần "Giao diện" và "Phê bình".

Mục 13.5.2 của Stroustrup (Phiên bản đặc biệt) bao gồm một ví dụ về chuyên môn của std::swap. Trích dẫn từ đó ...

Các chuyên ngành này là less()swap() được sử dụng trong thư viện chuẩn (16.3.9, 20.3.16). Ngoài ra, chúng là những ví dụ về các kỹ thuật áp dụng rộng rãi.

Tôi luôn đọc rằng chỉ ra rằng việc chuyên môn hóa std::swap là điều đúng và tôi chưa bao giờ lo lắng về ADL để đặt câu hỏi đó, nhưng có thể có một khoảng cách giữa "được sử dụng trong tiêu chuẩn thư viện "và" kỹ thuật áp dụng rộng rãi "- rằng kỹ thuật này không nên được sử dụng để chuyên std::swap để xử lý các loại không nằm trong std.

Cũng có thể có vấn đề về phong cách chưa được quyết định khi ấn bản đặc biệt được xuất bản lần đầu tiên. AFAIK, Stroustrup đã thêm một số phụ lục bổ sung và áp dụng một số sai sót, nhưng nếu không sửa đổi nội dung không đáng kể.

Dựa trên trang Wikipedia, có một vấn đề tiềm năng khi trộn bổ sung chuyên môn và ADL - đôi khi bạn có thể nhận được sự mơ hồ ngăn chặn bất kỳ tra cứu nào.Điều này chỉ chỉ xảy ra nếu bạn kết hợp hai kỹ thuật, và ADL là biết để dẫn đến vấn đề ngữ nghĩa anyway. Nhưng lập luận đó chỉ dẫn đến "không sử dụng ADL chút nào", nhưng ADL tồn tại vì một lý do.

Vâng, vâng, ADL tồn tại vì một lý do - để các hàm và toán tử không phải thành viên hoạt động cùng với một thời gian có thể nhìn thấy cùng với loại. Nhưng std::swap không được liên kết với một loại cụ thể - đó là chung chung, chỉ với các chuyên môn cụ thể được liên kết với các loại cụ thể. Nếu bạn muốn std::swap hiển thị, bạn muốn không gian tên std. ADL là không cần thiết để làm cho công việc đó và, như trang Wikipedia chỉ ra, có những lời chỉ trích của ADL.

Điều này có nghĩa là, về cơ bản, tôi không biết. Tôi có sự hợp lý hóa của tôi. Họ không nhất thiết phải đồng ý với các quy tắc phong cách phổ biến hơn. Chắc chắn nhận xét này chứng tỏ rằng không phải cần thiết để chuyên std::swap - bạn có thể tự cung cấp riêng cho mình swap và dựa vào ADL. Có lẽ đó là ưu tiên.

Tôi có thể sẽ quay lại và chỉnh sửa lại sau khi tôi đã kiểm tra.

+2

'std :: swap' nên ** không ** được chuyên biệt hoặc quá tải - thay vào đó, bạn nên đặt một hàm' swap' miễn phí trong cùng một không gian tên như kiểu được hoán đổi, và để ADL làm phần còn lại. – ildjarn

+0

@ildjarn - cảm ơn - Tôi không chắc bạn đã đúng chưa, nhưng hãy xem bản chỉnh sửa. – Steve314

+0

ADL đã bị phá vỡ rộng rãi trong các trình biên dịch chính trong một thời gian khá lâu, do đó, chuyên 'std :: swap' trở thành tiêu chuẩn thực hành. Tuy nhiên, với các trình biên dịch hiện đại, tuân thủ tiêu chuẩn hơn, cách giải quyết đó không còn cần thiết nữa. – ildjarn

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