如何处理每个内部std::列表



我有一个列表:std::list<MyType*>*

MyType是一个抽象类,我想处理每个满足条件的列表项,但列表可以包含也是std::list类型的元素,我也想处理它们。它可以有多个深度。

我更喜欢以迭代的方式处理它,但递归解决方案也很好。不幸的是,我还不知道该怎么做。

例如,列表如下:

Root std::list elements:
Type_A -> int
Type_B -> std::list
Type_C -> int
Type_B -> std::list
Type_A -> int
Type_C -> int
Type_A -> int
Type_A -> int
Type_D -> std::list
Type_A -> int
Type_A -> int
Type_A -> int

正如您所看到的,Type_A是一个标量类型,没有问题。Type_B也是一个列表,我必须处理Type_B元素。Type_B也可以有std::list项目,我也必须处理它们,等等。

代码示例:

void MyFunc(std::list<MyType*>* &statements)
{
std::list<MyType*>::iterator it;
for (it = statements->begin(); it != statements->end(); ++it)
{
if ((*it)->GetType() == _expectedType) // this type also has a list
{
std::list<MyType*>* statementList = dynamic_cast<ExpectedType*>(*it)->GetStatementList();
std::list<Statement*>::iterator it2 = statementList->begin();
// do some iterative or recursive process
}
}

您可以使用访问者模式

class Type_A;
class Type_B;
class Type_C;
class Type_D;
struct MyType_Visitor {
virtual void visit(Type_A & a) = 0;
virtual void visit(Type_B & b) = 0;
virtual void visit(Type_C & c) = 0;
virtual void visit(Type_D & d) = 0;
};
class MyType {
public:
virtual ~MyType() = default;
virtual void accept(MyType_Visitor & visitor) = 0;
// existing members
}
class Type_A : public MyType {
public:
void accept(MyType_Visitor & visitor) override {
visitor.visit(*this); // calls void visit(Type_A & a)
}
// existing members
};
class Type_B : public MyType {
std::list<MyType *> children;
public:
void accept(MyType_Visitor & visitor) override {
visitor.visit(*this); // calls void visit(Type_B & b)
for (MyType * child : children) {
child->accept(visitor); // also visit all the children
}
}
// existing members
};
class Type_C : public MyType {
public:
void accept(MyType_Visitor & visitor) override {
visitor.visit(*this); // calls void visit(Type_C & c)
}
// existing members
};
class Type_D : public MyType {
std::list<MyType *> other_things;
public:
void accept(MyType_Visitor & visitor) override {
visitor.visit(*this); // calls void visit(Type_D & d)
for (MyType * thing : other_things) {
thing->accept(visitor); // also visit all the children
}
}
// existing members
};

这样就可以为不同的情况定义不同的行为,例如

class PrintVisitor : public MyType_Visitor {
void visit(Type_A & a) override {
std::cout << "Type_A -> int" << std::endl;
}
void visit(Type_B & b) override {
std::cout << "Type_B -> std::list" << std::endl;
}
void visit(Type_C & c) override {
std::cout << "Type_C -> int" << std::endl;
}
void visit(Type_D & d) override {
std::cout << "Type_D -> std::list" << std::endl;
}
}
class MeetsConditionVisitor : public MyType_Visitor {
void visit(Type_A &) override { /* only care about B */ }
void visit(Type_B & b) override {
if (/* b specific something */) {
// stuff
}
}
void visit(Type_C &) override { /* only care about B */ }
void visit(Type_D &) override { /* only care about B */ }
}

如果潜在的任何子类都可以有子类,那么您可以使用一个虚拟成员函数来公开它。

class MyType {
public:
virtual ~MyType() = default;
virtual const std::list<MyType*> & children() {
// default -> no children
static const std::list<MyType*> empty;
return empty;
}
// existing members
}
class Type_B : public MyType {
std::list<MyType*> stuff;
public:
const std::list<MyType*> & children() override { return stuff; }
}
class Type_D : public MyType {
std::list<MyType*> things;
public:
const std::list<MyType*> & children() override { return things; }
}
void MyFunc(const std::list<MyType*> & statements)
{
for (auto * item : statements)
{
// stuff before visiting children
MyFunc(item->children());
// other stuff after visiting children
}
}

我想你可以使用多态性,让树中的每个节点都处理自己,就像这样:

class MyType
{
virtual void visit(Environment& env) const = 0;
};
class MyListType : public MyType
{
std::list<std::unique_ptr<MyType>> _elements;
void visit(Environment& env) const  override
{
for (const auto& node : _elements)
node->visit(env);
}
};
class MyLeafType : public MyType
{
void visit(Environment& env) const  override
{
// whatever
}
};

最新更新