c++ - 变体变量与非变体类型的交互

标签 c++ boost boost-variant

我正在尝试解决以下问题。我有一个指向自定义类 A 的指针 vector (它实际上是一个自定义结构,但 vector 足以替代这个问题)。 A 类实际上可以存储一个type_a 指针或一个type_b 指针(这些类型完全不同并且彼此不相关)。现在,这是通过保留两者来实现的,将它们设置为 NULL,然后稍后使用一堆 if/else 语句来检查它是哪种类型并执行适当的操作。

class A {
public:
  A() : p1(NULL), p2(NULL) {}

  type_a * p1;
  type_b * p2;
};

std::vector<A *> v;

...

if (v[0]->p1 != NULL) { /* do this */ }
else if (v[0]->p2 != NULL) { /* do that */ }

我计划向 A 类添加更多指针,因此上面的内容开始变得麻烦了。我目前正在尝试的解决方案是使用 boost::variant 来代替:

class A {
public:
  boost::variant<type_a*, type_b*> p;
};

不过,我遇到的问题是,我的一个操作涉及调用一个函数,该函数会根据我拥有的 p 类型为变量分配一些值。这就是现在的情况,在上述 if/else 语句之一中调用了适当的 process_stuff 函数:

class B { /*...*/ };

void process_stuff(type_a * p, B * b) {
  b->m_var = p->fn1();
}

void process_stuff(type_b * p, B * b) {
  b->m_var = p->fn2();
}

我不能让它与 boost::static_visitor 一起工作,因为(据我所知)我不能将非变体类型作为二进制访问中的参数,也不能我有一个非常量 operator() 使第二个变量成为访问者类的成员,并在 operator() 中用一元访问修改它。所以我很困惑如何将上面的 process_stuff 函数转换为与 boost::variant 一起玩。

顺便说一句,我不依赖于 boost::variant 并且会采用其他解决方案。

最佳答案

您只需要一个有状态的访问者。我是根据对访问者长相的模糊内存输入此内容的,但您应该能够纠正我犯的任何错误。

class process_stuff_visitor : public boost::static_visitor<void> {
  B* m_b;

public:
  process_stuff_visitor(B* b) : m_b(b) {}
  void visit(type_a* a) const { m_b->m_var = a->fn1(); }
  void visit(type_b* b) const { m_b->m_var = b->fn2(); }
};
// actual processing:
boost::apply_visitor(v[0], process_stuff_visitor(the_b));

或者,由于您分配给 B 的同一成员,您可以只提取值生成部分。

struct generate_stuff_visitor : public boost::static_visitor<TypeOfMVar> {
  TypeOfMVar visit(type_a* a) const { return a->fn1(); }
  TypeOfMVar visit(type_b* b) const { return b->fn2(); }
};
the_b->m_var = boost::apply_visitor(v[0], generate_stuff_visitor());

关于c++ - 变体变量与非变体类型的交互,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17326195/

相关文章:

c++ - Boost::访问者运算符过载时的变体 "Error: no match for call to [...]"

c++ - 在 C++ 中,当表达式涉及该对象时,将表达式分配给对象时是否有定义的操作顺序?

c++ - Cython 为 libcpp.list 赋值

c++ - 用于组合类的 Boost Karma 生成器

c++ - 更改 boost::error_info 可见性

c++ - 升压::变体; std::unique_ptr 和复制

c++ - 构建一个项目,其中文件待定参数

c++ - 在 C++ 中一般将 "optional"字段封装在结构中的最佳方法?

python - boost::python: Python 列表到 std::vector

c++ - `constructor required before non-static data member` - 我是否使用 `boost::variant` 解决了 C++ 核心问题 1360?