Reputation: 2828
I recently started to use Boost
C++ library and I am testing the any
class which can hold any data type. Actually I am trying to define the operator<<
to print easily the content of any variable of type any
(and sure, the class of the content should have the operator<<
defined too).
I only started by sample types ( int
, double
...) because they have be displayed by default. And till now, I have this code :
#include <boost/any.hpp>
#include <iostream>
#include <string>
using namespace std;
using namespace boost;
ostream& operator<<(ostream& out, any& a){
if(a.type() == typeid(int))
out << any_cast<int>(a);
else if(a.type() == typeid(double))
out << any_cast<double>(a);
// else ...
// But what about other types/classes ?!
}
int main(){
any a = 5;
cout << a << endl;
}
So the problem here is that I have to enumerate all possible types. Is there any way to cast the variable to a particular type
having the type_info
of this particular type
?
Upvotes: 3
Views: 3780
Reputation: 5339
Boost.Any any
With boost::any
you cannot do that as others have already noted in comments. That is because boost::any
forgets everything about the type of value it stores and requires you to know what type is there. While you have no way to enumerate every possible type.
The solution is to change boost::any
so that it forgets everything about the type of value it stores except for how to stream it out. Mooing Duck provided one solution in comments. Another would be to write a new version of boost::any
but extend its internals to support the streaming operation.
Boost.Spirit hold_any
Boost.Spirit already provides something like that in <boost/spirit/home/support/detail/hold_any.hpp>
.
Boost.TypeErasure any
A far better approach is however to use Boost.TypeErasure's any
as was mentioned by Kerrek SB in his comment.
An example for your case (use of <<
) would look like this:
#include <boost/type_erasure/any.hpp>
#include <boost/type_erasure/operators.hpp>
#include <iostream>
#include <string>
int main() {
typedef
boost::type_erasure::any<
boost::mpl::vector<
boost::type_erasure::destructible<>,
boost::type_erasure::ostreamable<>,
boost::type_erasure::relaxed
>
> my_any_type;
my_any_type my_any;
my_any = 5;
std::cout << my_any << std::endl;
my_any = 5.4;
std::cout << my_any << std::endl;
my_any = std::string("text");
std::cout << my_any << std::endl;
}
Upvotes: 1