如何阻止访客
How to stop a visitor?
一个典型的访问者模式设计如下:
template<class Visitor>
void processData(Visitor& visitor)
{
// maybe in sequence
visitor.process(...);
visitor.process(...);
...
// may have expensive computations
doExpensiveComputations();
// or in some loops
for (...)
visitor.process(...);
// or in some recursive calls
recursive(visitor);
}
当访问者对其余数据失去兴趣(例如找到答案)时,如何尽快返回?
请注意,任何需要更改设计的内容都是不可接受的,例如,我不想强迫Visitor::process返回一个值,并每次检查它。
我真正想做的是强制堆栈展开,我可以使用异常,但有人告诉我,对控制流使用异常是反模式的。
我认为Boost.Coroutine可能会有所帮助,但它仍然使用异常来进行堆栈展开。。。
我目前所做的如下:
struct Visitor
{
void process(T data)
{
if (stopped)
return;
...
}
...
};
但这仍然会影响执行,以及我们不需要的昂贵计算。
既然c++中除了可以展开堆栈的异常之外,没有其他可移植的方法,那么我应该在这里使用异常来控制流吗?
请注意,任何需要更改设计的内容都是不可接受的,例如,我不想强迫Visitor::process返回一个值,并每次检查它。
通过";设计;在这种情况下,我认为你的意思是";访问者的签名::process";。
我真正想做的是强制堆栈展开,我可以使用异常,但有人告诉我,对控制流使用异常是反模式的。
我应该在这里使用控制流的异常吗?
在这里使用异常不一定是反模式(就像它是一个"中断执行"系统一样——这可能是错误也可能不是错误)。
我曾经遇到过这种情况("使用异常来发出错误以外的信号"),我使用了一个thowable类型(它不是直接或间接继承自std::exception)。我的指导方针是";如果它继承自std::exception,则为错误;否则,它是处理不继续的信号";。
以这个实现为例:
struct ProcessingInterrupted final {}; // <--- thin/empty implementation
// not inheriting std exceptions
// and not inheritable
struct Visitor
{
void process(T data)
{
if(worldEnds)
throw ProcessingInterrupted{};
// ...
}
...
};
template<class Visitor>
bool process(Visitor& visitor)
{
try
{
processData(visitor); // taken from your example
return true;
}
catch(const ProcessingInterrupted&)
{
return false;
}
}
// client code
Visitor v;
/* auto success = */ process(v);
这样,ProcessingInterrupted类型告诉您正在发生的事情("处理被中断"),并且客户端代码(对于示例中的processData和我的过程)看起来是最小化的,并且具有明确定义的目的。
您可以禁用boost.coroutine的堆栈展开(类属性)示例/cpp03/asymmetric/same_fring.cpp显示了递归遍历树的一种变体——也许它会对您有所帮助。
- 在访客模式中组合访客
- 隐藏重载虚拟功能的模板化访客:SFINAE 在使用?
- C++提升::获取和访客
- 如何消除访客模式冗余?
- 虚拟模板函数:使用参数实现访客模式
- 究竟发生了什么,我们需要在 c++ 中双重调度/访客
- 访客设计模式和多层类层次结构
- VirtualBox访客添加汇编
- 具有不同返回类型的变体访客
- 基类中的访客模式
- 提升::访客操作员过载的变体"Error: no match for call to [...]"
- 为什么在 BGL 中的访客中无法更改边缘属性?
- 非周期访客C++
- C++ 访客模式与子类节点上的访客失去"is a"关系
- 访客模式适用于shared_ptr或原始指针?
- 提升变体和访客
- Lambdas的多态性访客
- 工厂返回提升::访客对象
- 提升的访客模式::任何
- 如何阻止访客