设计模式,对象矢量,两种可能的类型

时间:2016-08-27 10:09:36

标签: c++ design-patterns vector polymorphism

我需要在矢量中存储两种类型的对象,这两种类型几乎没有任何共同之处。

将它们存储在向量中后,我想迭代该向量并执行操作,具体取决于类型。

到目前为止我的想法:

  • 多态性。矫枉过正,并没有多大帮助,因为我可能会这样做:

    if(dynamic_cast<T1>() != nullptr) {
        ...
    } else {
       ...
    }
    
  • 合并两种类型(方法和字段)并添加一个布尔值,表示其类型是1还是2。

这两种模式对我来说都显得十分笨拙,有一个完全简单的解决方案,我根本就看不到。

第一种类型是这样的:

struct PatternMatch {
  int length;
  int indexInDict;
}

第二个 之一:

struct NoMatch {
  std::string rawChars;
}

2 个答案:

答案 0 :(得分:5)

使用boost::variant或任何其他“基于堆栈的歧视联合容器”。我还建议visiting the variant using lambdas

// Either `A` or `B`.
using my_type = boost::variant<A, B>;

std::vector<my_type> my_vec;

// ...`emplace_back` stuff into `my_vec`...

auto visitor = make_lambda_visitor<void>(
    [](A&) { /* do something with A */ },
    [](B&) { /* do something with B */ }
);

for(auto& x : my_vec)
{
     boost::apply_visitor(visitor, x);
}

请注意,C ++ 17将具有std::variant

答案 1 :(得分:1)

如果你知道你只有两种类型且这个数字将来不会增长,那么 C-ish 标记的联合就足够了,并且易于使用:

struct PatternMatch {
  int length;
  int indexInDict;
};

struct NoMatch {
  std::string rawChars;
};

struct TaggedUnion {
  enum { MATCH, NO_MATCH } flag;
  union {
    PatternMatch match;
    NoMatch noMatch;
  };
};

现在,您可以创建TaggedUnion s的向量,并检查flag数据成员以找出每个元素的实际类型。

相关问题