An elegant data type transfer method for `boost :: variant`

I need to find a better solution to pass the data type to boost::variantso that the function can gracefully retrieve the stored variable type. I put in an implementation that works for me, but I am concerned that there is a better way out.

// 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 above code, the implemented method can process both its own type and a custom data type. In the ideal case, we can do this without introducingenum TypePassIn

+5
source share
1 answer

You can use the (static) visitor pattern as shown in the Boost.Variant tutorial .

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"]);

}
+7
source

All Articles