Tại sao std::runtime_error
không cung cấp một hàm tạo chấp nhận một std::string&&
? Nhìn vào the constructors for std::string
, nó có một hàm tạo di chuyển, nhưng đặc tả noexcept
chỉ có cho C++ 14, chứ không phải C++ 11. Đây có phải là một sai lầm, một thời hạn đã bị bỏ lỡ hoặc tôi thiếu một cái gì đó?di chuyển hàm tạo cho std :: runtime_error
Trả lời
explicit runtime_error(string&&);
không tồn tại đơn giản chỉ vì nó sẽ không cung cấp bất kỳ tối ưu hóa.
Khi nó quay ra, một C++ 11 phù hợp runtime_error
không lưu trữ nội bộ std::string
. Lý do là các thành viên sao chép của runtime_error
không được ném ngoại lệ. Nếu không thì ngoại lệ sai có thể bị ném khi trình biên dịch sao chép đối tượng ngoại lệ trong quá trình ném nó.
Điều này ngụ ý rằng runtime_error
cần lưu trữ chuỗi được tính tham chiếu không thể thay đổi. Tuy nhiên, C++ 11 ngoại lệ việc triển khai COW cho std::string
. Việc triển khai std::string
đã chuyển sang "tối ưu hóa chuỗi ngắn" phải phân bổ trên bản sao xây dựng nếu độ dài của chuỗi vượt quá "giới hạn ngắn". Và không có giới hạn về độ dài của chuỗi được sử dụng để xây dựng một runtime_error
.
Vì vậy, hiệu quả C++ 11 (và chuyển tiếp) chứa hai triển khai các chuỗi:
std::string
: Đây thường là một loại ngắn chuỗi được tối ưu hóa với một constructor sao chép và sao chép phân có khả năng ném ngoại lệ.std::runtime_error
: Đây là (hoặc giữ) chuỗi được tính tham chiếu không thể thay đổi. Điều này sẽ không bao giờ ném vào việc sao chép hoặc sao chép bài tập.
Và
explicit runtime_error(string&&);
có thể không bao giờ (hiệu quả) nguồn lực chuyển từ "loại 1" chuỗi các "loại 2" chuỗi.
Chuỗi kiểu 2 trông như thế nào, không quan tâm? (Nếu đó là kiểu nội bộ được định dạng hộp đen, ẩn, được xác định thì đó là một câu trả lời đầy đủ.) –
Nó có thể trông giống như các phần không biến đổi của C++ 03 COW dựa trên 'std :: string'. Thật vậy, đó là chính xác những gì libC++ đã làm. Chuỗi kiểu 2 của nó có một ABI giống với gcc-4.2 'std :: string' để' runtime_error' có thể được ném từ libC++ và bị bắt bằng libstdC++ (và ngược lại), * trong cùng một ứng dụng *. –
Tại sao bạn muốn làm điều đó? –
- 1. thiếu std :: runtime_error trong + mingw qt
- 2. Ủy quyền cho hàm tạo di chuyển mặc định
- 3. using std :: di chuyển
- 4. Tại sao hàm tạo di chuyển không được gọi khi di chuyển trong một lambda?
- 5. std :: vector :: emplace_back và std :: di chuyển
- 6. Di chuyển hàm khởi tạo trên đối tượng dẫn xuất
- 7. Nên std :: mảng có di chuyển constructor?
- 8. Làm thế nào để kế thừa từ std :: runtime_error?
- 9. Không có hàm tạo mặc định nào không dẫn đến hàm tạo di chuyển không?
- 10. std :: make_shared, std :: unique_ptr và di chuyển nhà xây dựng
- 11. std :: di chuyển hoạt động C++
- 12. Tại sao hàm tạo di chuyển không được gọi?
- 13. Di chuyển hàm tạo và danh sách khởi tạo
- 14. Là một hàm tạo di chuyển `= mặc định 'tương đương với một hàm tạo di chuyển thành viên khôn ngoan?
- 15. Vật thể zombie sau std :: di chuyển
- 16. std :: di chuyển và bản đồ phân
- 17. std :: di chuyển bên trong nhà điều hành chuyển nhượng
- 18. Tại sao không std :: di chuyển trên một std :: unique_lock có bất kỳ tác dụng?
- 19. Cách chụp std :: unique_ptr "bằng cách di chuyển" cho lambda trong std :: for_each
- 20. Nên std :: di chuyển thả constness?
- 21. sự khác biệt giữa std :: di chuyển và std :: mong
- 22. Sự khác biệt giữa toán tử gán chuyển và di chuyển hàm tạo?
- 23. tài liệu tham khảo rvalue mà không std :: di chuyển
- 24. Tại sao hàm tạo bản sao này được gọi thay vì hàm tạo di chuyển?
- 25. Tại sao std :: di chuyển là cần thiết để gọi di chuyển gán nhà điều hành của std :: vector
- 26. std :: vector :: erase() không muốn di chuyển
- 27. Tại sao một hàm tạo di chuyển yêu cầu một hàm tạo mặc định cho các thành viên của nó?
- 28. std :: di chuyển trên một biến mà đã là T &&
- 29. Sao chép/di chuyển bài tập trong std :: vector :: erase() và std :: deque :: erase()
- 30. Làm thế nào để thực hiện một hàm tạo di chuyển cho một thừa kế hình kim cương?
Nếu 'std :: runtime_error' có một hàm tạo sử dụng' std :: string && ', chắc chắn nó sẽ không phải là một hàm tạo di chuyển. Một hàm tạo di chuyển sẽ lấy 'std :: runtime_error &&'. –
Tôi không chắc chắn tôi làm theo: đánh giá từ đầu có vẻ như câu hỏi của bạn là về 'runtime_error', nhưng sau đó bạn chuyển sang' std :: string'. Điểm gì bạn đang cố gắng để thực hiện? –
@AndyProwl: 'std :: runtime_error' có thể được tạo từ' const std :: string & 'hoặc từ' const char * what_arg'. Anh ta hỏi tại sao nó không thể được xây dựng từ một 'std :: string &&'. –