使用模板实现“访问者模式”(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
最满意答案
当我从这个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 ...
-
BeautifulSoup:如何用元素标签替换元素中的值?(BeautifulSoup: How to replace value in an element with an element tag?)[2021-12-03]
你的问题有两个部分: 将单个NavigableString“此文本是我的”转换为NavigableString,标记和另一个NavigableString。 用三个新元素替换NavigableString“这个文本就是我的”。 答案#1取决于你的情况。 具体取决于你如何确定文本的哪些部分需要链接。 我将使用正则表达式来查找字符串“text”: from bs4 import BeautifulSoup data = 'This text is my text
' ...
-
您可以使用基础数组来保存所有项目,例如以下HTML: //index 0 index 1 //index 2你可以使用replaceWith()来实现这一点,这里有一种方法: In [8]: from bs4 import BeautifulSoup In [9]: tree = BeautifulSoup('FooBar
Some text. ', 'xml') In [10]: newpara = 'Some new text. ...Python:ValueError:无法将字符串转换为float:(Python: ValueError: could not convert string to float:)[2023-01-10]
我检查了你在代码中检索到的xml文件 ,发现以xid="1824"开头的value元素没有内容,所以你得到一个空字符串,当你尝试将它转换为float时会引发错误。 解决方案是在转换为float之前检查item.content的内容item.content为空。 for item in data.by_tag('graph')[0].by_tag('value'): if item.content: graph1.append(float(unicode(item.content))) ...Beautifulsoup:ValueError:Tag.index:元素不在标签中(Beautifulsoup: ValueError: Tag.index: element not in tag)[2023-08-17]
当我从这个StackOverflow文章使用Martijn Peters的“clone()”方法时,它足够奇怪了: body = clone(soup.body) firstsoup.body.append(body) 为什么这个工作和“copy.copy()”没有,我还没有弄清楚。 没有重复身体标签的完整工作解决方案如下所示: body = clone(soup.body) for child in body.contents: firstsoup.b ...你的flatten_dict代码中有一些问题。 正如@PatrickMaupin所指出的那样,有时你的屈服值就像 - yield eprefix+k - 如果生成器确实产生了这个,那么dict()就不会对它起作用,这可能是导致问题的原因。 我相信你想要的东西 - yield eprefix+k,v 。 你有时会屈服 - flatten_dict(element, prefix=prefix) - (或flatten_list()对应物),这也flatten_list() 。 让我们举一个简单的例子 - >> ...如何在beautifulsoup4中通过文本内容获取标签元素(how can i get tag element by text content in beautifulsoup4)[2022-12-30]
您应该将find()与搜索功能一起使用,并检查表的.text以包含所需的文本: soup.find(lambda tag: tag.name == "table" and "part of text" in tag.text) 演示: >>> from bs4 import BeautifulSoup >>> >>> data = """ ... ...