I need to find a better solution to pass the data type into boost::variant
so that the function can retrieve the stored variate type elegantly. I have put up an implementation that works for me but I am concern there is a better way out there.
// file name: p192.cpp
#include <iostream>
#include <iomanip>
#include <string>
#include <map>
#include <boost/variant.hpp>
using namespace std;
enum TypePassIn
{
INT_TYPE,
DOUBLE_TYPE,
STRING_TYPE,
PERSON_TYPE,
LAST_TYPE = PERSON_TYPE
};
struct Person
{
Person(int _age, string _name) : age(_age), name(_name) {}
int age;
string name;
};
void PrintVariant(map<string, boost::variant<int, double, string, Person> > _mapValues, TypePassIn tpi)
{
switch(tpi)
{
case INT_TYPE:
cout << boost::get<int>(_mapValues["int"]) << endl;
break;
case DOUBLE_TYPE:
cout << setprecision (15) << boost::get<double>(_mapValues["double"]) << endl;
break;
case STRING_TYPE:
cout << boost::get<string>(_mapValues["string"]) << endl;
break;
case PERSON_TYPE:
cout << "Age: " << (boost::get<Person>(_mapValues["Person"])).age;
cout << ", Name: " << (boost::get<Person>(_mapValues["Person"])).name << endl;
break;
default:
break;
}
}
int main(void)
{ map<string, boost::variant<int, double, string, Person> > mapValues;
mapValues["int"] = 10;
PrintVariant(mapValues, INT_TYPE);
mapValues["double"] = 100.99;
PrintVariant(mapValues, DOUBLE_TYPE);
mapValues["string"] = "Hello world";
PrintVariant(mapValues, STRING_TYPE);
mapValues["Person"] = Person(10, "Tom");
PrintVariant(mapValues, PERSON_TYPE);
}
~/Documents/C++/boost $ ./p192
10
100.99
Hello world
Age: 10, Name: Tom
As you can see from the code above, the implemented method can handle both native type and customized data type. In the ideal case, we can do it without introducing the enum TypePassIn
You can use the (static) visitor pattern, as shown in the tutorial of Boost.Variant.
struct VariantPrinter : boost::static_visitor<void>
{
void operator()(int int_val)
{
std::cout << int_val << std::endl;
}
void operator()(double double_val)
{
std::cout << std::setprecision(15) << double_val << std::endl;
}
// etc.
};
void PrintVariant(const boost::variant<...>& the_variant)
{
boost::apply_visitor(VariantPrinter(), the_variant);
}
int main()
{
std::map<std::string, boost::variant<...> > mapValues;
mapValues["int"] = 10;
PrintVariant(mapValues["int"]);
}
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