C++ 变量与非变量类型的交互

C++ 变量与非变量类型的交互,c++,boost,boost-variant,C++,Boost,Boost Variant,我正在努力解决以下问题。我有一个指向自定义类a的指针向量(实际上它是一个自定义结构,但向量是这个问题的一个很好的替代品)。类A实际上可以存储type\u A指针或type\u b指针(这些类型完全不同,彼此不相关)。现在,这是通过保持这两种类型来实现的,将它们设置为NULL,然后稍后使用一组if/else语句来检查它是哪种类型并执行适当的操作 class A { public: A() : p1(NULL), p2(NULL) {} type_a * p1; type_b * p2

我正在努力解决以下问题。我有一个指向自定义类
a
的指针向量(实际上它是一个自定义结构,但向量是这个问题的一个很好的替代品)。类
A
实际上可以存储
type\u A
指针或
type\u 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 */ }
但我遇到的问题是,我的一个操作涉及调用一个函数,该函数将根据我使用的
p
类型为变量赋值。这就是现在的情况,在上面的一个
if/else
语句中调用相应的
process\u 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
一起工作,因为(据我所知)我不能在二进制访问中使用非变量类型作为参数,也不能使用非常量
操作符()
使第二个变量成为visitor类的成员,并在
操作符()
中使用一元访问修改该变量。因此,我不知道如何将上面的
process\u stuff
函数转换为与
boost::variant
一起使用


顺便说一句,我不喜欢boost::variant,我会采取其他的解决方案。

一种非常通用的面向对象的方法来完成您想要做的事情(如果我理解正确的话),就是为类型A和b(以及您想要的任何其他类型)创建一个虚拟基类,它定义了一个纯虚拟方法。此方法将为每个类型返回不同的值(例如,type_b::method可以返回'b',而type_a::method可以返回'a'),因此当您对未指定的类型调用该方法时,您将被告知它是什么类型


从那里,您可以使用标识方法的返回值作为switch语句的主题,或者使用其他一些常规控制结构来调用正确的行为。

一种非常通用的面向对象方法来完成您想要做的事情(如果我理解正确的话),就是为类型a和b创建一个虚拟基类(以及您想要的任何其他类型)定义纯虚拟方法。此方法将为每个类型返回不同的内容(例如,type_b::method可以返回“b”,而type_a::method可以返回“a”),因此,当您对未指定的类型调用该方法时,您将被告知它是什么类型


从那里,您可以使用标识方法的返回值作为switch语句的主题,或者使用其他一些常规控制结构来调用正确的行为。

您只需要一个有状态的访问者。我在一个关于访问者的模糊记忆中键入这个,但是您应该能够修复我犯的任何错误

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));
类进程\u stuff\u访问者:public boost::static\u访问者{
B*m_B;
公众:
进程(B*B):m(B){}
无效访问(type_a*a)const{m_b->m_var=a->fn1();}
无效访问(type_b*b)const{m_b->m_var=b->fn2();}
};
//实际处理:
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());
struct-generate\u-stuff\u-visitor:public-boost::static\u-visitor{
TypeOfMVar访问(type_a*a)const{return a->fn1();}
TypeOfMVar访问(type_b*b)常量{return b->fn2();}
};
_b->m_var=boost::apply_visitor(v[0],generate_stuff_visitor());

您只需要一个有状态的访问者。我在模糊的记忆中输入了这段文字,完全了解访问者的样子,但您应该能够修复我犯的任何错误

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));
类进程\u stuff\u访问者:public boost::static\u访问者{
B*m_B;
公众:
进程(B*B):m(B){}
无效访问(type_a*a)const{m_b->m_var=a->fn1();}
无效访问(type_b*b)const{m_b->m_var=b->fn2();}
};
//实际处理:
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());
struct-generate\u-stuff\u-visitor:public-boost::static\u-visitor{
TypeOfMVar访问(type_a*a)const{return a->fn1();}
TypeOfMVar访问(type_b*b)常量{return b->fn2();}
};
_b->m_var=boost::apply_visitor(v[0],generate_stuff_visitor());

简短回答:除非你能以某种方式统一类型,否则无论你以何种方式进行异类收集,它都可能是丑陋和笨拙的。不幸的是,我不能统一类型。我认为如果我能(例如)使用一个非常量
操作符()的话,这一切都会非常有效
static\u visitor
中。简短回答:除非你能以某种方式统一类型,否则不管你以何种方式进行异类收集,它都可能是丑陋和笨拙的。不幸的是,我不能统一类型。我想如果我能使用一个非常量
操作符()
static\u visitor
中的
谢谢,但是
type\u a
type\u b
是“上帝赐予的”,所以我无法控制它们。啊,如果是这样的话,我会同意杰里·科芬对形势的评估。谢谢,但是
type\u a
type\u b
是“上帝赐予的”所以我无法控制他们。啊,如果是这样的话,我会同意杰里·科芬对形势的评估。