2015-01-18 15 views
9

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

+0

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 &&'. –

+0

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? –

+0

@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 &&'. –

Trả lời

14

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:

  1. 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ệ.

  2. 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.

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.

+1

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 đủ.) –

+5

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 *. –

+0

Tại sao bạn muốn làm điều đó? –

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