- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我对 Typelists 很感兴趣。在这个网址 http://drdobbs.com/184403813有一个很好的例子说明如何使用类型列表创建访问者模式。
关于这个例子我有两个问题。我的两个问题在本主题的末尾。
考虑下面的代码:
void SomeOperation(DocumentItem* p)
{
if (TextArea* pTextArea = dynamic_cast<TextArea*>(p))
{
... operate on a TextArea object ...
}
else if (VectorGraphics* pVectorGraphics =
dynamic_cast<VectorGraphics*>(p))
{
... operate on a VectorGraphics object ...
}
else if (Bitmap* pBitmap = dynamic_cast<Bitmap*>(p))
{
... operate on a Bitmap object ...
}
else
{
throw "Unknown type passed";
}
}
根据 Alexandrescu 的说法,这段代码的不便之处在于:
In addition to being thoroughly ugly, the code above has the conceptual problem of being unable to catch at compile time the "forgot to handle this type"
即将到来的类型列表:
#include<iostream>
class null_typelist {};
template <class H, class T>
struct typelist
{
typedef H head;
typedef T tail;
};
template<class T1, class T2=null_typelist, class T3=null_typelist, class T4=null_typelist> struct cons;
template <class T1>
struct cons<T1, null_typelist, null_typelist,null_typelist>
{
typedef typelist<T1, null_typelist> type;
};
template <class T1, class T2>
struct cons<T1, T2, null_typelist, null_typelist>
{
typedef typelist<T1, typelist<T2,null_typelist> > type;
};
template <class T1, class T2, class T3>
struct cons<T1, T2, T3, null_typelist>
{
typedef typelist<T1, typelist<T2, typelist<T3,null_typelist> > > type;
};
template <class T1, class T2, class T3, class T4>
struct cons
{
typedef typelist<T1, typelist<T2, typelist<T3,typelist<T4, null_typelist> > > > type;
};
template <class tlist> class AdHocVisitor;
template <class H, class T>
class AdHocVisitor< typelist<H, T> > : public AdHocVisitor<T>
{
public:
virtual void Visit(H*) = 0;
template <class SomeClass>
void StartVisit(SomeClass* p)
{
if (H* pFound = dynamic_cast<H*>(p))
{
Visit(pFound);
}
else
{
AdHocVisitor<T>::StartVisit(p);
}
}
};
template <class H>
class AdHocVisitor< typelist<H, null_typelist> >
{
public:
virtual void Visit(H*) = 0;
template <class SomeClass>
void StartVisit(SomeClass* p)
{
if (H* pFound = dynamic_cast<H*>(p))
{
Visit(pFound);
}
else
{
throw "Unknown type passed";
}
}
};
struct DocElement{virtual ~DocElement(){};};
struct TextArea: DocElement{};
struct Bitmap: DocElement{};
struct VectorGraphics: DocElement{};
int main()
{
typedef cons<TextArea,Bitmap,VectorGraphics>::type MyHierarchy;
DocElement *p = new Bitmap;
struct ConcreteVisitor : AdHocVisitor<MyHierarchy>
{
void Visit(TextArea* p){std::cout << "I'm a textarea" << "\n";}
void Visit(VectorGraphics* p){std::cout << "I'm a VectorGraphics" << "\n";}
void Visit(Bitmap* p){std::cout << "I'm a Bitmap" << "\n";}
};
ConcreteVisitor visitor;
visitor.StartVisit(p);
delete p;
std::cin.get();
}
1- 我们还有 dynamic_cast 和一个虚函数。所以我不太清楚引入类型列表的好处?
2- 在本文末尾,Alexandrescu 给出了一些改进此代码的建议,但我不太了解如何实现这些建议,有人可以帮助我吗?
谢谢
最佳答案
如果您有 50 个 DocElement 类型怎么办?对于第一个示例,您需要 50 个 if 语句,对于第二个示例,您只需要一个包含 50 个元素的类型列表。
您还可以考虑添加另一个 DocElement 时会发生什么。在第一个示例中,您需要更改 if-else 语句。使用类型列表,您只需将新类型添加到类型列表的末尾即可。
类型列表代码可能看起来有很多开销,但您只需编写一次,然后就可以使用它,而不是添加 ifs 或 case 和代码(随着时间的推移它们会变得相当大),您只需添加类型到类型列表。从维护的角度来看,类型列表代码远比一个巨大的 switch 语句或数十或数百个 if 好得多。
至于改进,我不知道,我仍在等待可变参数模板和类型别名包含在 VS 中,以便我可以进一步简化代码。
每当我看到一大堆重复代码时,我就会开始考虑类型列表和元编程,让编译器来完成工作,而不是无聊的程序员。最好的部分是什么?你在运行时得到零惩罚,它和 ifs 一样高效(如果你小心内联)
关于c++ - 类型列表访问者模式示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5578607/
我正在尝试为玩具语言实现一个解析器。 我已经编写了语法,但是当我尝试从 CST 创建 AST 时遇到了问题。 我定义了一个继承自 MyParserVisitor 的类哪里ASTNode是一个虚拟类,我
我想创建子类对象,它会与其他子类对象做出不同的 react (类可以欢迎另一个类,但不是全部)代码原理源自访客设计模式: class A { public : virtual bool isW
我正在玩 boost A* 算法,从在以下位置找到的示例开始:http://www.boost.org/doc/libs/1_37_0/libs/graph/example/astar-cities.
我正在为我的网站构建一个访问者和点击率计数器,当然,访问者每天是一个唯一的 ip,点击率是每次请求页面时! 我已经创建了数据库和系统来插入和更新我保存统计信息的表! 我正在苦苦挣扎的是,如何对日期进行
如何放弃使用 IE6 浏览我的网站? 就像是 : 如果 ie6 => 死 我正在使用 ASP.Net 谢谢 最佳答案 在asp.net中你可以查看Request.Browser在 Session_st
我目前正在编写解析器。解析器生成一个 AST,然后我使用各种遍历来处理它。 AST 是(简化的): type LiteralExpr = { readonly kind: 'literal',
我正在使用 Antlr4 的 C++ 访问者 api 来遍历解析树。但是,我正在努力使其正常运行。也就是说,我不确定如何使用 visitChildren(ParseTree *tree) 调用。 我为
我的问题是理论性的,而不是如何去做。我想知道专家们如何处理我将在下面描述的情况。 我有一个使用 Angular 和 Breeze 的 SPA。身份验证是基于 token 的。我在 Angular 中设
我有一棵树(在图形意义上)表示一棵树(在物理意义上)。树表示为 BGL 邻接列表,其中每个顶点包含半径和位置属性,即,我的图以以下形式定义 struct TreeVertexType { doub
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 10 年前。 Improve thi
是否可以将域限制为仅允许使用特定浏览器的访问者? 我正在构建一个应用程序,到目前为止它只在 Chrome 中进行过测试,所以我只想在 Beta 测试期间允许 Chrome 用户。基本上,我想在进行测试
你好,我正在尝试实现一个 AST Clang 访问者,这是我的代码。 class ExampleVisitor : public RecursiveASTVisitor { private:
我想构建一个访问者(用于 dikstra),并将 initialise_vertex 用作“颜色映射”修饰符。我想根据条件从搜索中排除一些顶点。所以我想在算法的初始部分将一些顶点设置为“黑色”。 cl
我正在尝试编写一个网站,提示每 10,000 名访问者输入一封可以存储在文本文件中的电子邮件。 我设置了一个点击计数器,它将访问者总数输出到一个文本文件中,因此是否可以将脚本设置为类似于 "如果 nu
我正在尝试将 AST 与 ANTLR4 一起使用,并使用以下文件: 生成器.java import org.antlr.v4.runtime.ANTLRInputStream; import org.
在 BGL 中,我不太明白如何在 bfs/dfs 搜索期间访问图中顶点的固有颜色(白色表示未触及,灰色表示已访问,黑色表示已完成)。 有人可以说明如何从 dfs/bfs 访问者中访问顶点的颜色吗?例如
当用户访问您的网站时,如何获取用户的信息? IP地址 苹果地址 用户个人资料名称 操作系统名称 操作系统版本 操作系统注册到(姓名/公司) 计算机名 浏览器名称 浏览器版本 ISP 名称/Intern
我最近开始使用 Amazon S3 为访问者提供图像,因为这会减少服务器负载。现在,出现了一个新问题:今天我查看了我的 AWS 账单。我注意到我有一大笔账单等着我——20 天内总共有 4TB 的 AW
session 劫持 所以我有一个小问题。我正在尝试识别访问者,这很难通过 $_SERVER veriables 来实现,如以下问题所述:Preventing session hijacking .
我有一个带有两个边定义的图,如下所示: isDepartment: [organisation] -> [organisation] hasAccess: [user] -> [organisatio
我是一名优秀的程序员,十分优秀!