bad_any_cast being thrown but no idea why

I have been pulling my hair out over this bug for a day or two now. Here's the synopsis. I have a boost::any object which is storing a std::string. Any test I do to check if indeed the any object is holding onto a std::string object verifies what I already know. For instance, the following function always returns true for my boost::any object: bool is_string(const boost::any& operand) { return ( operand.type() == typeid(std::string) ); } Also if I just print out the typeinfo information for the boost::any object is also shows that its holding onto a std::string: std::stringstream ss; ss << "any object: " << obj.type().name() << ", a string: " << typeid(std::string).name(); yields, any object: Ss, a string: Ss However, whenever I try and actually cast my object to a string (boost::any_caststd::string(...)), I always get "boost::bad_any_cast: failed conversion using boost::any_cast". Could this possibly be a compiler issue? I saw one other thread where "-fvisibility=hidden" was causing some problems for boost::program_options and std::string. In my situation, I have a library which is responsible for creating those boost::any objects. Then its in a separately compiled library where I am getting the problems.

John Yamokoski wrote:
I have been pulling my hair out over this bug for a day or two now. Here's the synopsis. I have a boost::any object which is storing a std::string. Any test I do to check if indeed the any object is holding onto a std::string object verifies what I already know. For instance, the following function always returns true for my boost::any object:
bool is_string(const boost::any& operand) { return ( operand.type() == typeid(std::string) ); }
Also if I just print out the typeinfo information for the boost::any object is also shows that its holding onto a std::string:
std::stringstream ss; ss << "any object: " << obj.type().name() << ", a string: " << typeid(std::string).name();
yields,
any object: Ss, a string: Ss
However, whenever I try and actually cast my object to a string (boost::any_caststd::string(...)), I always get "boost::bad_any_cast: failed conversion using boost::any_cast".
Could this possibly be a compiler issue? I saw one other thread where "-fvisibility=hidden" was causing some problems for boost::program_options and std::string. In my situation, I have a library which is responsible for creating those boost::any objects. Then its in a separately compiled library where I am getting the problems. _______________________________________________
Hi John - The problem is that the RTTI id's are different between your lib and the executable. You can use the undocumented and very useful unsafe cast: boost::unsafe_any_cast< std::string>( ... ) Of course, this creates a problem since it is not safe and if the any doesn't contain a std::string there will be a surprise. I think the typical way of handling this (or at least what I do) is something like this: ---------------------- template< typename T > bool contains( const boost::any& a ) { try { // we do the comparison with 'name' because across shared library boundries we get // two different type_info objects return( std::strcmp( typeid( T ).name(), a.type().name() ) == 0 ); } catch( ... ) { } return false; } ... if( contains< std::string >( foo ) ) { bar = boost::unsafe_any_cast< std::string >( &foo ); } ------------------------- Hope this helps you out. michael -- ---------------------------------- Michael Caisse Object Modeling Designs www.objectmodelingdesigns.com

I have been pulling my hair out over this bug for a day or two now. Here's the synopsis. I have a boost::any object which is storing a std::string. Any test I do to check if indeed the any object is holding onto a std::string object verifies what I already know. For instance, the following function always returns true for my boost::any object:
bool is_string(const boost::any& operand) { return ( operand.type() == typeid(std::string) ); }
Also if I just print out the typeinfo information for the boost::any object is also shows that its holding onto a std::string:
std::stringstream ss; ss << "any object: " << obj.type().name() << ", a string: " << typeid(std::string).name();
yields,
any object: Ss, a string: Ss
However, whenever I try and actually cast my object to a string (boost::any_caststd::string(...)), I always get "boost::bad_any_cast: failed conversion using boost::any_cast".
Could this possibly be a compiler issue? I saw one other thread where "-fvisibility=hidden" was causing some problems for boost::program_options and std::string. In my situation, I have a library which is responsible for creating those boost::any objects. Then its in a separately compiled library where I am getting the problems. _______________________________________________
Hi John -
The problem is that the RTTI id's are different between your lib and the executable. You can use the undocumented and very useful unsafe cast:
boost::unsafe_any_cast< std::string>( ... )
Of course, this creates a problem since it is not safe and if the any doesn't contain a std::string there will be a surprise.
Michael, Well its great to hear there's some sort of explanation for this. Unfortunately, from my compiler, I get: no matching function for call to 'unsafe_any_cast(const boost::any&)' I believe I have installed Boost version 1.40. I will gladly downgrade to an earlier version if unsafe_any_cast was finally eliminated in 1.40. Otherwise is there another way to deal with RTTI ID issues? This is the first I have heard of them. Ahhh.. so close though. J.D.

John Yamokoski wrote:
Hi John -
The problem is that the RTTI id's are different between your lib and the executable. You can use the undocumented and very useful unsafe cast:
boost::unsafe_any_cast< std::string>( ... )
Of course, this creates a problem since it is not safe and if the any doesn't contain a std::string there will be a surprise.
Michael,
Well its great to hear there's some sort of explanation for this. Unfortunately, from my compiler, I get:
no matching function for call to 'unsafe_any_cast(const boost::any&)'
I believe I have installed Boost version 1.40. I will gladly downgrade to an earlier version if unsafe_any_cast was finally eliminated in 1.40. Otherwise is there another way to deal with RTTI ID issues? This is the first I have heard of them. Ahhh.. so close though.
John - It is still in the interface: https://svn.boost.org/trac/boost/browser/tags/release/Boost_1_40_0/boost/any... Did you remember the template parameter? boost::unsafe_any_cast< std::string>( ... ) Do you have a small code snippet that reproduces the problem? michael -- ---------------------------------- Michael Caisse Object Modeling Designs www.objectmodelingdesigns.com

Hi John -
The problem is that the RTTI id's are different between your lib and the executable. You can use the undocumented and very useful unsafe cast:
boost::unsafe_any_cast< std::string>( ... )
Of course, this creates a problem since it is not safe and if the any doesn't contain a std::string there will be a surprise.
Michael,
Well its great to hear there's some sort of explanation for this. Unfortunately, from my compiler, I get:
no matching function for call to 'unsafe_any_cast(const boost::any&)'
I believe I have installed Boost version 1.40. I will gladly downgrade to an earlier version if unsafe_any_cast was finally eliminated in 1.40. Otherwise is there another way to deal with RTTI ID issues? This is the first I have heard of them. Ahhh.. so close though.
John -
It is still in the interface:
https://svn.boost.org/trac/boost/browser/tags/release/Boost_1_40_0/boost/any...
Did you remember the template parameter?
boost::unsafe_any_cast< std::string>( ... )
Do you have a small code snippet that reproduces the problem?
michael
Got it! I wasn't passing in a pointer to the any object.. it should have been: boost::unsafe_any_cast< std::string>( &obj ) Now its working! Michael thanks so much - you have saved some of my hair! ;) btw, still curious about this RTTI stuff. Is there another way to handle this other than doing unsafe casts? J.D.
participants (2)
-
John Yamokoski
-
Michael Caisse