While testing the examples trough the boost cpp libraries book I noticed that changing the type stored inside a boost::any variable may lead to an illegal access instead of an exception:
good:
boost::any a = 1;
bool *p = boost::any_cast<bool>(&a); // ok, bad cast exception
bad:
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
My question therefore is: is this a bug as it seems or is it some underlying fact related to templates usage that I am not aware of?
I understand the documentation differently:
Returns: If passed a pointer, it returns a similarly qualified pointer to the value content if successful, otherwise null is returned. If T is ValueType, it returns a copy of the held value, otherwise, if T is a reference to (possibly const qualified) ValueType, it returns a reference to the held value.
Throws: Overloads taking an any pointer do not throw; overloads taking an any value or reference throws bad_any_cast if unsuccessful.
So:
The success or failure of the conversion depends on the stored type and target type.
The manifestation of failure though, depends on whether you pass a pointer to any_cast
or not. If you pass a pointer, the manifestation is a nullptr
; otherwise, the manifestation is an exception.
Consider for example this code:
#include <boost/any.hpp>
#include <iostream>
int main() {
boost::any a = 1;
This seems to contradict the statement in your question - since it takes a pointer, it doesn't throw, but the pointer is nullptr
:
bool *p = boost::any_cast<bool>(&a);
// Prints true
std::cout << std::boolalpha << (p == nullptr) << std::endl;
This is how it looks when it's OK:
int *q = boost::any_cast<int>(&a);
// Prints false
std::cout << std::boolalpha << (q == nullptr) << std::endl;
This throws, because it doesn't take a pointer:
try {
boost::any_cast<bool>(a);
}
catch(...) {
std::cout << "caught" << std::endl;
}
Same for a string stored type:
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;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With