【问题标题】:How to use Boost Variant with struct objects C++如何将 Boost Variant 与结构对象 C++ 一起使用
【发布时间】:2017-09-05 01:26:14
【问题描述】:

我有两个类,根据key 的性质,我想从boost::variant 中获取结构值。代码如下所示。

#include <iostream>
#include <boost/variant.hpp>

using namespace std;

class A {
    public:
    struct greeting {
        string hello;
};


class B {
    public:
    struct greeting {
        string bye;
    };
};

typedef boost::variant<A::greeting, B::greeting> greet;

greet getG(string key) {
    greet g;
    if (key == "A") {
        g.hello = "MY ENEMY"; // this line doesn't work
    }
    else {
        g.bye = "MY FRIEND"; // nor this line
    }
    return g;
};

int main() {
    A a;
    B b;
    greet h = getG("A");
    A::greeting my = boost::get<A::greeting>(h);
    cout << my.hello << endl;
    return 0;
}

我得到的确切错误是: error: no member named 'hello' in 'boost::variant&lt;A::greeting, B::greeting, boost::detail::variant::void_, boost::detail::variant::void_, ...&gt;' g.hello = "MY ENEMY";error: no member named 'bye' in 'boost::variant&lt;A::greeting, B::greeting, .../&gt;' g.bye = "MY FRIEND";

感谢任何帮助。

【问题讨论】:

  • 虽然行号可以很容易地找到特定的行,但它也让我们很难复制代码并自己尝试。标出错误所在行的注释就足够了。
  • 至于你的问题,使用boost::get获取具体结构的参考。 (有关如何使用它的示例,请参阅Boost variant tutorial

标签: c++ boost struct conditional boost-variant


【解决方案1】:

变体类型没有.hello.bye 成员。您可以通过“访问者”功能访问它们。但是当访问者没有被应用到正确的类型时,你仍然需要决定要做什么。我认为您没有以预期的方式使用 Boost.Variant。 (例如条件句不好闻)。

http://www.boost.org/doc/libs/1_61_0/doc/html/variant/reference.html#variant.concepts.static-visitor

struct hello_visitor : boost::static_visitor<>{
    string const& msg;
    hello_visitor(string const& msg) : msg(msg){}
    void operator()(A::greeting& t) const{
        t.hello = msg;
    }
    void operator()(B::greeting& t) const{
        // throw? ignore? other?
    }
};

struct bye_visitor : boost::static_visitor<>{
    string const& msg;
    bye_visitor(string const& msg) : msg(msg){}
    void operator()(A::greeting& t) const{
        // throw? ignore? other?
    }
    void operator()(B::greeting& t) const{
        t.bye = msg;
    }
};


greet getG(string key) {
    greet g;
    if (key == "A") { // is "key" handling the type, if so you can delegate this to the library instead of doing this.
        boost::apply_visitor(hello_visitor("MY ENEMY"), g); 
    }
    else {
        boost::apply_visitor(bye_visitor("MY FRIEND"), g); 
    }
    return g;
};

【讨论】:

  • 我刚刚删除了行号。我测试了代码,得到了error: no matching function for call to bye_visitorhello_visitor。你介意指出我缺少什么吗?
  • 此代码现在可以使用。目前还不完全清楚你想要做什么。看起来您正在将一些手动变体(带有条件)与实际的 Boost.Variant 混合。 Boost.Variant 的想法是您不必处理“真实类型”的决策树。
  • 正是我需要的。谢谢。
猜你喜欢
  • 1970-01-01
  • 2018-07-21
  • 1970-01-01
  • 2013-07-09
  • 1970-01-01
  • 2013-10-25
  • 2012-07-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多