2012-10-18 30 views
9

Tiếp theo là không thể:Tại sao tăng :: định dạng không thể được chuyển đổi trực tiếp thành std :: string?

std::string s = boost::format("%d") % 1; // error 

Bạn phải explicitely gọi str() phương pháp:

std::string s = (boost::format("%d") % 1).str(); // OK 

Nó sẽ chỉ là cú pháp đường, nhưng tại sao không chỉ cần thêm chuyển đổi?

+0

Không phải là quá tải của% đủ không? :) – jrok

+2

Tôi không chắc bạn đang tìm kiếm loại câu trả lời nào ở đây. Bạn có hỏi liệu có bất kỳ vấn đề ngữ nghĩa nào ngăn không cho Boost thực hiện một điều như vậy không? Hay bạn chỉ nói, "Họ nên làm theo cách này." –

+1

Tôi đang cố gắng hiểu các vấn đề ngữ nghĩa. Tôi thường nghĩ rằng các thư viện tăng cường được thiết kế tốt. –

Trả lời

9

Nó không phải là một điều rất tốt nếu một chuyển đổi ngầm có thể ném ngoại lệ. Chuyển đổi thành chuỗi sẽ mặc định ném một ngoại lệ nếu ít đối số được nạp vào format hơn mức cần thiết. Ví dụ:

std::string f() 
{ 
    boost::format fmt("%d"); 
    // forgot to feed an argument 
    std::string s = fmt; // throws boost::io::too_few_args 
    widget.set_title(fmt); // throws boost::io::too_few_args 
    return fmt; // throws boost::io::too_few_args 
} 

Chuyển đổi tiềm ẩn này làm cho khó phát hiện và phân tích các phần mã có thể ném ngoại lệ. Nhưng rõ ràng các cuộc gọi .str() cung cấp một gợi ý về các ngoại lệ có thể xảy ra, đảm bảo an toàn ngoại lệ cho mã xung quanh, cũng như (trong trường hợp cụ thể này) gợi ý kiểm tra lại mã trước để ngăn ngoại lệ nói trên xảy ra ngay từ đầu .

+0

Cả hai câu trả lời (điều này và một trong BigBoss) đều cung cấp các lý do chính đáng cho không có chuyển đổi tiềm ẩn. Nhưng tôi phải chấp nhận chỉ một :-) –

+0

@mr_georg Cảm ơn :) – usta

10

Tôi nghĩ lý do cho điều này là tương tự như std::stringstream, trong bối cảnh mà bạn cũng nên sử dụng .str() để chuyển đổi dòng để chuỗi và tương tự cho boost::formatter và lý do là như sau:

std::string s1 = "Hello ", s2 = "World"; 
format("%s.") % s1 + s2; 

Bây giờ nếu boost::formatter là chuyển đổi hoàn toàn thành std::string sau đó nó tạo ra "Hello .World", bởi vì format("%s.") % s1 sẽ được chuyển thành "Hello". và sau đó nó sẽ được chuyển đổi hoàn toàn thành std::string và sử dụng operator+ để thêm nó với s2, nhưng có lẽ hầu hết các lập trình viên đều muốn có "Hello World". và đó sẽ là nguồn gây nhầm lẫn. Nhưng trong trường hợp đó không có chuyển đổi ngầm tồn tại biên dịch sẽ tạo ra lỗi này (vì không có operator+ cho boost::formatterstd::string) và để bạn có thể sửa chữa nó hoặc là format("%s.") % (s1 + s2) hoặc str(format("%s.") % s1) + s2

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