防止与复合访问者重复
Prevent duplication with a composite visitor
我目前有两个访问者,他们都能正常工作。
#include <iostream>
#include <vector>
struct VisitorA
{
void DoSomething(){}
};
struct VisitorB
{
void DoSomething(){}
};
template <typename TVisitor>
static void RunAlgorithm(TVisitor& visitor);
int main()
{
VisitorA visitorA;
VisitorB visitorB;
RunAlgorithm(visitorA);
RunAlgorithm(visitorB);
}
template <typename TVisitor>
void RunAlgorithm(TVisitor& visitor)
{
visitor.DoSomething();
}
现在我想在算法中应用两个访问者。我见过一个"复合"访问者,它存储多个访问者,并简单地将呼叫转发给每个访问者。要做到这一点,我似乎必须创建一个"ParentVisitor"类并从中派生,这样我就可以将ParentVisitor*存储在一个容器中:
#include <iostream>
#include <vector>
struct VisitorParent
{
void DoSomething(){}
};
struct VisitorA : public VisitorParent
{
void DoSomething(){}
};
struct VisitorB : public VisitorParent
{
void DoSomething(){}
};
struct VisitorComposite : public VisitorParent
{
void DoSomething()
{
for(unsigned int i = 0; i < Visitors.size(); ++i)
{
Visitors[i]->DoSomething();
}
}
std::vector<VisitorParent*> Visitors;
};
static void RunAlgorithm(VisitorParent& visitor);
int main()
{
// VisitorA visitor;
// RunAlgorithm(visitor);
VisitorA visitorA;
VisitorB visitorB;
VisitorComposite visitorComposite;
visitorComposite.Visitors.push_back(&visitorA);
visitorComposite.Visitors.push_back(&visitorB);
RunAlgorithm(visitorComposite);
}
void RunAlgorithm(VisitorParent& visitor)
{
visitor.DoSomething();
}
这样做的问题是,如果访问者有一些重复的功能,它将被执行两次。我曾想过将重复的代码移到VisitorParent,但后来我不知道如何对重复的部分说"只为其中一个访问者运行父代码,而不为其他访问者运行任何东西"。这似乎是"手动"的——有没有更好的机制来申请两个(或更多)访客?
在我看来,除了抽象的基本访问者类,您实际上总共需要四个具体访问者:
- 一个包含A和B中的常见运算
- 一个包含A特有的操作
- 一个包含B唯一的操作
- 一个合成器,可以通过抽象基类调用多个其他访问者
然后,通过与uniqueA组合common来处理原始访问者A的角色,通过与uniqueB组合common处理访问者B的角色,并且通过组合common、uniqueA和uniqueB来处理组合操作。
重复数据消除可以在合成器的出厂函数中完成,但您可能不想在合成器类中"烘焙"重复数据消除,以保留更多的灵活性。
使用访问者模式,如果运行它,您不会真的期望任何东西"中断"。因此,当您运行两次某个东西时,它可能会起作用是否运行两次是比访问者更高级别的问题,因此它不应该影响访问者的设计。
所以在这种情况下,手动可能是好的。
复合体的角色可能应该是一个控制器。它可能知道,如果一个访问者成功了,那么另一个访问者也不适合运行。为访问者添加一个返回值将为组合提供控制运行内容所需的反馈。控制器关心的是运行什么,访问者保持沉默。
相关文章:
- 访问者访问变体并返回不同类型时出错
- 算术复合运算符重载为非成员
- C++模板函数中的初始化 - 新的初始值设定项表达式列表被视为复合表达式
- 时间复杂度 当具有复合数据类型(如元组或对)时?
- HDF5Cpp 扩展复合数据集超板问题
- 返回复合模式的复合对象不返回整个对象
- 如何处理模板类中的复合类型
- 重载 C++ 中的复合运算符 (.*)
- C++析构函数调用两次,堆栈分配的复合对象
- H5Tget_member_type() 返回复合 HDF5 数据类型的奇怪值
- 复合类型的动态数组
- 为什么这个复合语句作为用大括号和括号括起来的语句序列似乎不是有效的语句表达式
- 对复合分配中的"常量"的混淆
- 使用自定义访问者时具有自定义类型的提升变体失败(源自 boost::static_visitor)
- C 复合赋值运算符 ^= 平均值
- 复合赋值运算符C++概念
- 有没有办法改变概念中的复合需求返回的类型?
- 在未初始化的变量上使用复合赋值运算符(+=, ..)不是C++中的UB?
- 复合赋值运算符是否不如 C++ 精确?
- 防止与复合访问者重复