使用boost访问者在类型之间进行转换

时间:2011-10-27 12:30:41

标签: c++ boost visitor boost-variant

假设我有一个

boost::variant<std::string, int> myVariant;

在这个对象中,我保存数据库中的数据,数据库通常是整数或文本,但有时候是作为文本存储在数据库中的时间。 所以我想知道我是否可以创建一个访问者,当访问带有字符串的variant对象时,返回一个类型为'tm'的结构。这样的事情:

class timeVisitor : public boost::static_visitor<boost::shared_ptr<tm> >
{
public:
    boost::shared_ptr<tm> operator()(string &str) const
    {
        boost::shared_ptr<tm> dst(new tm());
        strptime(str.c_str(), "%Y-%m-%d", dst.get());
        return dst;
    }
};

然后为了使用它:

boost::shared_ptr<tm> result = boost::apply_visitor( timeVisitor(), myVariant );

问题是,我不想在访问者中创建tm结构并乱用一些共享指针和东西。我更喜欢将已经创建的一个给访问者和内部只是初始化。 像(在使用意义上)的东西:

tm result;
int returnCode = boost::apply_visitor( timeVisitor(result), myVariant );

访问者将使用strptime初始化我的结果tm结构,如果转换为returnCode时出现问题,甚至会返回。 有谁知道如何实现这一目标?我能以某种方式定义带有两个参数的访问者......或者其他可能的东西吗?

2 个答案:

答案 0 :(得分:1)

您的简单示例调用应该有效。向访问者添加一个构造函数,该构造函数接受引用并存储它,如:

 tm* target;
 timeVisitor( tm& a ) : target(&a) {}
 int operator()(string &str) const {
      strptime(str.c_str(), "%Y-%m-%d", target);
 }

答案 1 :(得分:1)

事实上,完全允许在创作时给参观者一个参数。您在问题结束时编写的代码是执行此操作的好方法:

tm result;
int returnCode = boost::apply_visitor( timeVisitor(result), myVariant );

以下是访问者的外观:(未经过我的测试,可能会出现轻微的语法错误)

class timeVisitor : public boost::static_visitor<bool>
{
public:
    timeVisitor(tm& s):m_tm(s) {}

    bool operator()(string &str) const
    {
        return strptime(str.c_str(), "%Y-%m-%d", m_tm.get());
        // in case of error, NULL pointer is converted to false automatically
    }
protected:
    tm& m_tm;
};