1

Can anyone guide me on how to solve this problem. I have a boost::variant.

typedef boost::variant <
int,
std::string,
bool,
double,
vector<int>,
vector<string>,
vector<bool>,
vector<double>
> boostVar;

I am trying to create overload [] operator as member function of a class ABC something like this (this is just a dummy implementation)

class ABC
{
    //some map of (key, value) pair that where key is string and value is of type boostVar
    boostVar [](const string key)
    {
       boostVar temp;
       //some operation that fills up temp based on value of key
       return temp;
    }
}

So while retrieving the a particular value using this implementation, it forces user to specify

int key1Val         = boost::get<int>(ABC["KEY1"]);
bool key2Val        = boost::get<bool>(ABC["KEY2"]);
vector<int> key3Val = boost::get<vector<int>>(ABC["KEY3"]);

my question is:

How should I go about implementing this if I want to access the values like below (i.e. without boost::get<>)

int key1Val         = ABC["KEY1"];
bool key2Val        = ABC["KEY2"];
vector<int> key3Val = ABC["KEY3"];

The implementation should give warning to user if the say: KEY1 does not match int, KEY2 does not match bool and so on.

legameeternoforall
  • 69
  • 1
  • 2
  • 10

1 Answers1

1

You'd need to use a class to wrap the boost variant and add the conversion behaviours. At it's simplest - in the common case where realistically client code won't be trying to delete dynamically allocated instances using pointers to the base (boost::variant<...>*) - it could look something like this:

struct Variant : boost::variant<int, std::string, ...etc...>
{
    operator int() const { return boost::get<int>(*this); }
    operator std::string() const { return boost::get<std::string>(*this); }
    ...etc...
};

This will provide the same checks get<> provides: compile time checks that you're trying to assign to one of the types the variant could hold at runtime, and runtime checks that it does actually hold the exact destination type when you try to assign from it.

If you can't be sure client code won't delete via the base class pointer, consider private inheritance or composition (you will need to do more work to expose any other variant functionality your client code may want to access).

(ABC::operator[](const std::string& key) const can just return such a Variant).

Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
  • Thanks @Tony. I was able to implement it. To learn such 'way of coding' can you recommend some books I can read. I am basically looking to develop my approach while solving such problems. And I would like to know if there is any book that teaches you different approaches/tricks to solving a particular problems. – legameeternoforall Sep 07 '17 at 20:43
  • 1
    @legameeternoforall: You're welcome. Books - that's a big question (and off-topic, though S.O.'s C++ topic homepage has a recommended book list). At one level, the "way of coding" there is applying a design pattern called an "adapter" - you can read about such things at a very high level in [Design Patterns](https://en.wikipedia.org/wiki/Design_Patterns). For a gentle introduction to C++ template hackery, I'd still recommend Modern C++ Design by Alexandrescu. But, I don't keep up with C++ book releases, so may not be the best person to ask.... – Tony Delroy Sep 10 '17 at 01:12
  • I am finding this book very useful! This will certainly help me write clean and flexible code! – legameeternoforall Dec 03 '17 at 18:21