C++ là statically ngôn ngữ đã nhập. Loại số boost::any
là giá trị thời gian hoạt động ; bất kỳ any
cụ thể nào cũng có thể có bất kỳ loại nào. Đó là kinda điểm.
Không có any::type_value
, vì đó sẽ phải là thời gian biên dịch . Và any
là cấu trúc thời gian chạy.
Hãy xem xét điều này:
void TakeAnAny(boost::any a)
{
a::type_value& i2 = any_cast<a::type_value &>(a);
}
là loại gì any::type_value
? Việc gọi TakeAnAny
với hầu như bất kỳ loại nào là đều hợp pháp. Không có loại biên dịch đơn lẻ mà any::type_value
có thể giảm xuống. Và do đó, không có cách nào để trình biên dịch xác định loại. Kể từ khi C++ được gõ tĩnh, bạn đang hosed.
Mục đích cuối cùng của bất kỳ là loại tẩy xóa. Tôi có một số giá trị. Và tôi muốn truyền điều đó cho một số chức năng khác. Quá trình này sẽ trải qua một số lớp giao tiếp khác nhau. Nhưng tôi không nhất thiết muốn tất cả những lớp khác nhau đó biết chính xác loại tôi đang sử dụng. Tôi chỉ cần bản thân mình và điểm đến dự định của tôi để biết loại. Vì vậy, bạn dính nó vào một any
và bạn ổn. Mọi người khác chỉ nhìn thấy any
và cả hai bạn đều biết nó kết thúc tốt đẹp.
Quy trình này chỉ hoạt động vì cả nguồn và đích đều biết loại giá trị thực. Nếu bạn không biết loại, thì bạn không nên sử dụng any
. Mục đích của any
không có chức năng ngồi ở đó và đưa nó vào một loạt các loại có thể (đó là những gì boost::variant
là dành cho). Mục đích là để xóa các loại từ chữ ký của một hàm.
Điều này cho phép những thứ như tin nhắn và tín hiệu chung. Bạn đăng ký một số xử lý sự kiện với một hệ thống. Bạn kích hoạt sự kiện mất một tham số any
. Người kích hoạt sự kiện biết rằng sự kiện "Nhấp chuột" luôn luôn có tham số vec2
. Vì vậy, mọi trình xử lý "MouseClick" sẽ chuyển nó thành một số vec2
. Sự kiện "KeyPress" có thể vượt qua int32_t
. Vì vậy, những người xử lý đúc nó vào loại đó. Và kể từ đó trở đi. Mọi người đều biết những gì loại nó thực sự mất.
Việc này được thực hiện với void*
. Vấn đề ở đây là bạn có các vấn đề về quyền sở hữu (any
là một giá trị, trong khi void*
là một con trỏ). Ngoài ra, một số void*
được xóa theo kiểu mà không có cách nào để kiểm tra xem dàn diễn viên của bạn có chính xác hay không. any
thực sự chỉ là một loại & giá trị an toàn void*
; điều này ngăn bạn truyền sang loại sai.
Bạn thực sự không muốn any
. Trường hợp sử dụng của bạn dường như không muốn variant
. Những gì bạn muốn là một mẫu . Đó là một loại khác nhau của điều, và nó sẽ cho phép bạn làm những gì bạn thực sự muốn: có một chức năng có thể sử dụng bất kỳ loại cụ thể, trong khi vẫn có thể biết chính xác loại đó là gì.
Tất nhiên, các mẫu có giới hạn riêng.
Bạn chỉ đơn giản là _can't_ làm điều này với Boost.Any, do đó, sử dụng Boost.Variant thay vì sẽ là câu trả lời cơ bản. – ildjarn
* Tại sao * bạn có cần phải làm điều này? – GManNickG