2013-10-25 17 views
17

Tôi muốn viết loại vùng chứa. Vùng chứa này có phương thức chèn có hai chuyên môn - đầu tiên sử dụng các nhà xây dựng sao chép để sao chép dữ liệu từ một vùng chứa đến một phần tử vùng chứa khác một cách khôn ngoan. Nếu nhà xây dựng bản sao ném ngoại lệ, tôi chỉ hoàn tác mọi thay đổi đối với vùng chứa như không có gì xảy ra.Mã an toàn ngoại lệ và di chuyển ngữ nghĩa

Chuyên môn thứ hai sử dụng hàm tạo di chuyển và đó là nơi mọi thứ trở nên phức tạp. Khi tôi di chuyển các mục từ một thùng chứa đến một phần tử vùng chứa khác theo phần tử, di chuyển hàm tạo có thể ném ngoại lệ. Nếu điều này xảy ra - Tôi đã thực sự lộn xộn khi một số yếu tố được di chuyển và các yếu tố khác vẫn ở trong những nơi ban đầu. Nếu tôi cố gắng di chuyển các phần tử trở lại - tôi có thể có ngoại lệ khác.

Có thể viết một cái gì đó như thế này trong cách ngoại lệ an toàn hoặc ngoại lệ an toàn và di chuyển ngữ nghĩa là loại trừ lẫn nhau?

Trả lời

22

Sử dụng std::move_if_noexcept khi viết mã nhạy cảm ngoại lệ, nhưng vẫn muốn sử dụng ngữ nghĩa di chuyển khi thời gian biên dịch an toàn để làm như vậy.

Xem Scott Meyers' talk at GoingNative 2013 để biết thêm chi tiết về điều đó.

PS: Ồ vâng, hãy nhớ rằng nếu nội dung của bạn không được sao chép có thể xây dựng được, bạn sẽ di chuyển nó bất kể việc ném/không xuất hiện công cụ di chuyển của bạn.

+0

Tôi không nhận được "PS". Bạn có thể xây dựng? –

+1

Nếu di chuyển của bạn có thể ném, std :: move_if_noexcept fallbacks để sao chép. NHƯNG! nếu công cụ của bạn không có một hàm tạo bản sao, std :: move_if_noexcept nói 'Meh' và di chuyển nó (những gì khác nó có thể làm thực sự?), có thể nhận được một ngoại lệ và để lại container của bạn trong trạng thái thực sự xấu. –

+2

Một lựa chọn khủng khiếp để xác định nó theo cách IMO ... bạn có thể tạo phiên bản của riêng bạn (không có '&& std :: is_copy_constructible :: value') sẽ gây ra lỗi thời gian biên dịch thay thế. – Joe

1

Sử dụng ủy quyền hàm tạo là một cách để thực hiện việc này. Nếu hàm tạo không ủy nhiệm (có thể là một hàm không có đối số, đặt thành viên của bạn thành mặc định) đã kết thúc và hàm khởi tạo ủy nhiệm, tiêu chuẩn nói rằng trạng thái cục bộ của bạn bị xóa. Bằng cách này bạn không thể bị rò rỉ. Tôi đã học được điều này ngay hôm nay trong this talk.

Nhân tiện: bạn đang triển khai loại container nào mà STL chưa thiết lập cho bạn?

+0

Bảng băm buckoo :) – Lazin

+0

không bao giờ nghe nói về điều đó nhưng nó có vẻ thú vị như xa như [Wikipedia] (http://en.wikipedia.org/wiki/Cuckoo_hashing) giải thích nó ^^ – HaMster

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