使用`boost :: variant`来存储和检索值而不传递类型信息

时间:2012-01-19 00:54:12

标签: c++ boost

在理想情况下,我想以下列方式使用ClassVariant:

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

但是,我只能实现以下代码,该代码需要检索语句来提供类型信息,如下所示:

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

如您所见,int(0)作为类型信息提供。有没有办法可以消除这个限制。因此不需要类型信息。

#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

2 个答案:

答案 0 :(得分:1)

你不能这样做,模板参数推导仅适用于参数,而不适用于函数的返回值。你最好的选择是抛弃operator()来寻找像get<T>()这样的正常函数。我不能指出标准中的相关部分,但对我来说太模糊了。

注意:如果可能出现这种情况,我的猜测是boost :: variant已经有get函数,其中不需要指定T

编辑:请参阅此question

答案 1 :(得分:0)

您应该与访问者一起使用boost :: variant来访问其中的值。见here