I have this test snippet
#include <boost/any.hpp>
#include <iostream>
#include <vector>
#include <bitset>
#include <string>
class wrapper {
int value;
char character;
std::string str;
public:
wrapper(int i, char c, std::string s) {
value = i;
character = c;
str = s;
}
void get_data(){
std::cout << "Value = " << value << std::endl;
std::cout << "Character = " << character << std::endl;
std::cout << "String= " << str << std::endl;
}
};
int main(){
std::vector<boost::any> container;
container.push_back(10);
container.push_back(1.4);
container.push_back("Mayukh");
container.push_back('A');
container.push_back(std::bitset<16>(255) );
wrapper wrap(20, 'M', "Alisha");
container.push_back(wrap);
std::cout << boost::any_cast<int>(container[0]) << std::endl;
std::cout << boost::any_cast<double>(container[1]) << std::endl;
std::cout << boost::any_cast<std::string>(container[2]);
std::cout << boost::any_cast<char>(container[3]) << std::endl;
std::cout << boost::any_cast<std::bitset<16>>(container[4]);
auto p = boost::any_cast<wrapper>(container[5]);
p.get_data();
return 0;
}
In this boost::any_cast
gives bad_casting exception for std::string
. It means for some reason it is not able to typecast boost::any
into std::string
. While other classes like bitset
or my own user defined class is working. Can you please tell me why & a way out of this?
"Mayukh"
is not a std::string
, it is a const
array of 7 characters {'M', 'a', 'y', 'u', 'k', 'h', '\0'}
. In C++14, "Mayukh"s
is a std::string
after using namespace std::literals::string_literals;
.
In C++11, std::string("Mayukh")
is a std::string
as well.
boost::any
only supports converting back to the exact same type (well, up to some decay/const/etc). It does not support conversions between the types. See boost any documentation:
Discriminated types that contain values of different types but do not attempt conversion between them, i.e.
5
is held strictly as an int and is not implicitly convertible either to"5"
or to5.0
. Their indifference to interpretation but awareness of type effectively makes them safe, generic containers of single values, with no scope for surprises from ambiguous conversions.
Augmenting any
with extra smart conversions can be done. For example, a pseudo-any that takes an incoming type, and possibly auto-converts it (so it won't store short
s: it converts all signed integral types to int64_t
and unsigned to uint64_t
, it converts "hello"
to std::string("hello")
, etc) before storing it.
That's because "Mayukh"
is not a std::string
. It's a const char[7]
, which would decay into const char*
:
boost::any a = "Mayukh";
std::cout << a.type().name() << '\n'; // prints PKc, pointer to const char
if (boost::any_cast<const char*>(&a)) {
std::cout << "yay\n"; // prints yay
}
If you want to be able to use any_cast<std::string>
, you'd need to put it in as a std::string
:
container.push_back(std::string("Mayukh"));
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