2016-10-13 17 views
5

Khi kiểm tra các ví dụ máng sách thư viện cpp tăng, tôi nhận thấy rằng việc thay đổi loại được lưu trữ bên trong một tăng :: bất kỳ biến nào có thể dẫn đến truy cập bất hợp pháp thay vì ngoại lệ:boost :: bất kỳ thay đổi kiểu nào dẫn đến truy cập bất hợp pháp

tốt:

boost::any a = 1; 
bool *p = boost::any_cast<bool>(&a); // ok, bad cast exception 

xấu:

boost::any a = std::string { "Boost" }; 
a = 1; 
bool *p = boost::any_cast<bool>(&a); // no exception thrown 
std::cout << std::boolalpha << *p << '\n'; // illegal access 

câu hỏi của tôi do đó là: là này một lỗi như nó có vẻ hay là một số thực tế cơ bản liên quan đến việc sử dụng các mẫu mà tôi không nhận thức được?

+3

... "Vâng, đừng di chuyển cánh tay của bạn theo cách đó." –

+1

'v = boost :: any a = 1; bool * p = boost :: any_cast (&a); // ok, bad cast exception' gì? Không, điều đó không xảy ra. – Yakk

+0

Cảm ơn bạn, bạn đã đúng, cũng như Ami Tavory đã chỉ ra rằng tôi đã xem xét phần mã sai. Kể từ khi giải thích của ông là âm thanh tôi đã cập nhật mã trong câu hỏi. –

Trả lời

6

Tôi hiểu the documentation cách khác nhau:

Returns: Nếu được thông qua một con trỏ, nó sẽ trả về một con trỏ có trình độ tương tự như hàm lượng giá trị nếu thành công, nếu không null được trả lại. Nếu T là ValueType, nó trả về một bản sao của giá trị được giữ, nếu không, nếu T là tham chiếu đến (có thể const đủ điều kiện) ValueType, nó trả về một tham chiếu đến giá trị được giữ.

Ném: Quá tải lấy bất kỳ con trỏ nào không ném; quá tải tham gia bất kỳ giá trị hoặc tham chiếu nào ném bad_any_cast nếu không thành công.

Vì vậy:

  1. Sự thành công hay thất bại của việc chuyển đổi phụ thuộc vào loại và mục tiêu loại lưu trữ.

  2. Biểu hiện của lỗi mặc dù phụ thuộc vào việc bạn có chuyển con trỏ đến any_cast hay không. Nếu bạn vượt qua một con trỏ, biểu hiện là nullptr; nếu không, biểu hiện là một ngoại lệ.

Hãy xem xét ví dụ mã này:

#include <boost/any.hpp> 
#include <iostream> 

int main() { 
    boost::any a = 1; 

Điều này có vẻ mâu thuẫn với tuyên bố trong câu hỏi của bạn - vì nó có một con trỏ, nó không ném, nhưng con trỏ là nullptr:

bool *p = boost::any_cast<bool>(&a); 
    // Prints true 
    std::cout << std::boolalpha << (p == nullptr) << std::endl; 

Đây là cách nó trông khi nó OK:

int *q = boost::any_cast<int>(&a); 
    // Prints false 
    std::cout << std::boolalpha << (q == nullptr) << std::endl; 

này ném, bởi vì nó không mất một con trỏ:

try { 
     boost::any_cast<bool>(a); 
    } 
    catch(...) { 
     std::cout << "caught" << std::endl; 
    } 

Tương tự cho một chuỗi loại lưu trữ: "Bác sĩ, điều đau khổ khi tôi di chuyển cánh tay của tôi theo cách này"

a = std::string { "Boost" }; 
    p = boost::any_cast<bool>(&a); 
    // Prints true 
    std::cout << std::boolalpha << (p == nullptr) << std::endl; 
    try { 
     boost::any_cast<bool>(a); 
    } 
    catch(...) { 
     std::cout << "caught again" << std::endl; 
    } 
} 
Các vấn đề liên quan