首页 \ 问答 \ 使用模板实现“访问者模式”(Implement the “visitor pattern” with templates)

使用模板实现“访问者模式”(Implement the “visitor pattern” with templates)

我试图以参数方式实现访问者模式的修改版本,以这种方式避免每个具体元素都有重载的“通用访问者”,但是,由于我在模板编程方面没有很多经验我不知道如何完成“模式”。

码:

// test.cpp
#include <iostream>
#include <vector>

using namespace std;

struct Base
{
    virtual ~Base() {}
    virtual void visit() = 0;
};

template<typename Visitor>
struct ElementBase : public Base
{
    // No virtual.
    void visit()
    {
        _e.visit(this);
    }

private:
    Visitor _e;
};

// Atoms.
template<typename Visitor>
struct ElementA : public ElementBase<Visitor>
{
    ElementA() : a(5) {}

    int a;
};

// Visitors.
struct VisitorA
{
    void visit(ElementBase<VisitorA> *a)
    {
        ElementA<VisitorA>* elto = dynamic_cast<ElementA<VisitorA>*>(a);

        cout << elto->a << endl;
    }

    /*
    void visit(ElementA<VisitorA> *a)
    {
        cout << a->a << endl;
    }
    */
};

std::vector<Base*> v;

int main()
{
    v.push_back(new ElementA<VisitorA>());

    for (auto i : v)
        i->visit();
}

这工作正常,其输出为5(如预期的那样)。 但是,我假装的是直接使用VisitorA中“访问”的第二个(注释)版本。

显然,这不起作用,因为“this”具有ElementBase <...> *类型。

如何将指针“this”向下转换为ElementBase中的实际派生类?


I'm trying to implement a modified version of the visitor pattern in a parametric manner, avoiding in this way a "universal visitor" with a overload for each concrete element, but, due to I haven't a lot of experience in template programming I don't know how I can complete the "pattern".

Code:

// test.cpp
#include <iostream>
#include <vector>

using namespace std;

struct Base
{
    virtual ~Base() {}
    virtual void visit() = 0;
};

template<typename Visitor>
struct ElementBase : public Base
{
    // No virtual.
    void visit()
    {
        _e.visit(this);
    }

private:
    Visitor _e;
};

// Atoms.
template<typename Visitor>
struct ElementA : public ElementBase<Visitor>
{
    ElementA() : a(5) {}

    int a;
};

// Visitors.
struct VisitorA
{
    void visit(ElementBase<VisitorA> *a)
    {
        ElementA<VisitorA>* elto = dynamic_cast<ElementA<VisitorA>*>(a);

        cout << elto->a << endl;
    }

    /*
    void visit(ElementA<VisitorA> *a)
    {
        cout << a->a << endl;
    }
    */
};

std::vector<Base*> v;

int main()
{
    v.push_back(new ElementA<VisitorA>());

    for (auto i : v)
        i->visit();
}

This works fine and its output is 5 (as expected). But that I pretend is to make the same but directly with the second (commented) version of the "visit" in VisitorA.

Obviously, this doesn't work because "this" has the type ElementBase<...>*.

How can I downcast the pointer "this" to the actual derived class inside ElementBase?


原文:https://stackoverflow.com/questions/13865360
更新时间:2023-06-10 06:06

最满意答案

当我从这个StackOverflow文章使用Martijn Peters的“clone()”方法时,它足够奇怪了:

 body = clone(soup.body)
 firstsoup.body.append(body)

为什么这个工作和“copy.copy()”没有,我还没有弄清楚。

没有重复身体标签的完整工作解决方案如下所示:

       body = clone(soup.body)
       for child in body.contents:
          firstsoup.body.append(clone(child))

当我在第一行使用“copy.copy()”时,这也起作用,但当我在最后一行中使用“copy.copy()”替换“clone()”时不起作用。


Strange enough it works when I am using Martijn Peters' "clone()" method from this StackOverflow post:

 body = clone(soup.body)
 firstsoup.body.append(body)

Why this works and "copy.copy()" doesn't, I have yet to figure out.

The complete working solution without duplication of the body tags looks like this:

       body = clone(soup.body)
       for child in body.contents:
          firstsoup.body.append(clone(child))

This also works when I am using "copy.copy()" in the first line but not when I replace "clone()" by "copy.copy()" in the last line.

相关问答

更多
  • 评论中指出,人们可以简单地将card作为unicode。 但是,这导致process_card函数错误输出, slice indices must be integers or None or have an __index__ method 。 事实证明,这个错误与card不再是bs4对象这一事实有关,因此无法访问bs4函数。 相反, card只是unicode,错误是与unicode相关的错误。 因此,首先需要将card变成汤,然后从那里开始。 这有效! def process_card(unicode ...
  • 你的问题有两个部分: 将单个NavigableString“此文本是我的”转换为NavigableString,标记和另一个NavigableString。 用三个新元素替换NavigableString“这个文本就是我的”。 答案#1取决于你的情况。 具体取决于你如何确定文本的哪些部分需要链接。 我将使用正则表达式来查找字符串“text”: from bs4 import BeautifulSoup data = '

    This text is my text

    ' ...

  • 您可以使用基础数组来保存所有项目,例如以下HTML:
    //index 0
    index 1
    //index 2