q0987
q0987

Reputation: 35982

usage of `boost::variant` to store and retrieve the value without passing the type information

In the ideal case, I would like to use the ClassVariant in the following way:

  // store & retrieve int
  map<string, ClassVariant> mapValues;
  mapValues["int_fieldX"] = ClassVariant(20);
  int fieldX = (mapValues["int_fieldX"])();
  // Or int fieldX = (mapValues["int_fieldX"]); 

However, I can ONLY implement the following code that requires the retrieving statement to feed the type info as follows:

  int fieldB = (mapValuesTwo["int_fieldB"])(int(0));

As you can see int(0) is provided as type info. Is there a way that I can remove this limitation. So that the type info is NOT needed.

#include <iostream>
#include <iomanip>
#include <string>
#include <map>
#include <boost/variant.hpp>

using namespace std;

typedef boost::variant<int, double, string> VarIntDoubleString;

class ClassVariant
{
public:
  ClassVariant() : m_value(int(0)) {}
  ClassVariant(VarIntDoubleString _val) : m_value(_val) {}

  template<typename T>  
  T operator()(const T&) const
  {
    return boost::get<T>(m_value);
  }

private:
  VarIntDoubleString m_value;
};

int main(void)
{
  map<string, ClassVariant> mapValuesTwo;

  // store & retrieve int
  mapValuesTwo["int_fieldB"] = ClassVariant(20);
  int fieldB = (mapValuesTwo["int_fieldB"])(int(0));
  cout << "fieldB: " << fieldB << endl;

  // store & retrieve string
  mapValuesTwo["int_fieldD"] = ClassVariant("Hello world");
  string fieldD = (mapValuesTwo["int_fieldD"])(string(""));
  cout << "fieldD: " << fieldD << endl;
}

// Output
fieldB: 20
fieldD: Hello world

Upvotes: 1

Views: 2387

Answers (2)

nttstar
nttstar

Reputation: 341

You SHOULD use boost::variant together with visitor to access the value in it. see here

Upvotes: 0

J.N.
J.N.

Reputation: 8421

You can't do this, template argument deduction works only on the parameters, not on the return value of a function. Your best choice is to ditch operator() for a normal function like get<T>(). I can't point to the relevant line in the standard though, too obscure for me.

Note: if such a thing was possible, my guess would be that boost::variant would already have a get function where specifying T is not requried.

EDIT: see this question

Upvotes: 1

Related Questions