使用 boost Visitor 在类型之间进行转换

发布于 2024-12-12 02:57:52 字数 970 浏览 3 评论 0原文

假设我有一个

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

在这个对象中,我保存数据库中的数据,通常是整数或文本,但有时是以文本形式存储在数据库中的时间。 所以我想知道是否可以创建一个访问者,当访问带有字符串的变体对象时,返回一个“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 时出现问题,甚至会返回。 有谁知道如何实现这一点?我可以以某种方式定义带有两个参数的访问者......或者其他参数吗?

Let's say that I have a

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

In this object I keep data from a database, which is usually integer or text, but sometimes is a time stored in the database as text.
So I wonder if I can create a visitor, that when visiting the variant object with a string into it, returns a struct of type 'tm'. Something like that:

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;
    }
};

Then in order to use it:

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

The thing is, that I don't want to create the tm struct into the visitor and mess around with some shared pointers and stuff. I prefer to give an already created one to the visitor and inside just to be initialized.
Something like (in the sense of usage):

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

The visitor will just initialize with strptime my result tm struct and will even return if there was a problem with the conversion into returnCode.
Does anyone know how this can be achieved? Can I define somehow visitor that take two parameters ... or maybe something else?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

风为裳 2024-12-19 02:57:52

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

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

Your straightforward example call should work. Add a constructor to the visitor that takes a reference and stores it, like:

 tm* target;
 timeVisitor( tm& a ) : target(&a) {}
 int operator()(string &str) const {
      strptime(str.c_str(), "%Y-%m-%d", target);
 }
尽揽少女心 2024-12-19 02:57:52

事实上,它完全可以让访问者在创作时有一个论据。您在问题末尾编写的代码是执行此操作的好方法:

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;
};

Indeed, it's perfectly allowed to give the visitor an argument at creation. The code you wrote at the end of your question is the good way to do it :

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

Here is how the visitor should looks like : (not tested on my side, slight syntax error possible)

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;
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文