如果我boost::variant支持的所有类型都使用相同的方法,那么有没有办法一般地调用它(即不为每个方法单独调用它static_visitor)?
我正试图让这样的东西起作用:
class A
{
void boo() {}
};
class B
{
void boo() {}
};
class C
{
void boo() {}
};
typedef boost::variant<A, B, C> X;
void foo(X& d)
{
x.boo();
}
Run Code Online (Sandbox Code Playgroud)
但它无法编译说'boo' : is not a member of 'boost::variant<T0_,T1,T2>'.
目前,我有一些类都继承自接口,因此可以多态地使用它们的单个共享方法.我还希望能够通过访问者使用这些类,因为所有其他方法对于每个具体类都是唯一的.我希望boost::variant可能是在这里实现我自己的访问者机制的更好的替代方案.是吗?
我正在Swift 2.2中为工作项目实现访问者模式.
因此,我不需要简化我的源代码并节省一些时间,我将使用Oktawian Chojnacki在swift中的访客模式示例.
protocol PlanetVisitor {
func visit(planet: PlanetAlderaan)
func visit(planet: PlanetCoruscant)
func visit(planet: PlanetTatooine)
}
protocol Planet {
func accept(visitor: PlanetVisitor)
}
class PlanetAlderaan: Planet {
func accept(visitor: PlanetVisitor) { visitor.visit(self) }
}
class PlanetCoruscant: Planet {
func accept(visitor: PlanetVisitor) { visitor.visit(self) }
}
class PlanetTatooine: Planet {
func accept(visitor: PlanetVisitor) { visitor.visit(self) }
}
class NameVisitor: PlanetVisitor {
var name = ""
func visit(planet: PlanetAlderaan) { name = "Alderaan" }
func visit(planet: PlanetCoruscant) { name …Run Code Online (Sandbox Code Playgroud) 来自https://en.cppreference.com/w/cpp/utility/variant/visit:
visit?我不明白“访问者的选定调用”?示例代码
// Don't understand what this means, can explain? It's a templated func with trailing return type but no body?
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
// Why would the visitor function use && instead of &?
std::visit([](auto&& arg){std::cout << arg;}, v);
Run Code Online (Sandbox Code Playgroud) 是否可以在 C# 中创建用户可扩展的访问者模式?(最好是 .net 3.5)
我在库中有一组类,我希望使用访问者模式向其中添加功能。问题是库的用户也可以创建自己的类。这意味着您需要创建一个特殊的访问者来接受新的类类型,但我们的 Accept 方法被设置为接收基本类型。如何让派生类在派生访问者中调用正确的方法。
或者是否有另一种方式来做“如果是这种类型,就这样做”?
一些示例代码:
/* In library */
namespace VisitorPattern.System
{
interface IThing
{
void Accept(SystemVisitor visitor);
void ThingMethodA(...);
void ThingMethodB(...);
}
class SystemThingA : IThing
{
public void Accept(SystemVisitor visitor) { visitor.Visit(this); }
...ThingMethods...
}
class SystemThingB : IThing
{
public void Accept(SystemVisitor visitor) { visitor.Visit(this); }
...ThingMethods...
}
class SystemThingC : IThing
{
public void Accept(SystemVisitor visitor) { visitor.Visit(this); }
...ThingMethods...
}
class SystemVisitor
{
public SystemVisitor(object specialSystemServices) { }
public virtual …Run Code Online (Sandbox Code Playgroud) 我在OCaml中实现了一个简单的类C语言,并且像往常一样,AST是我的中间代码表示.由于我将在树上进行一些遍历,我想实现访问者模式以减轻痛苦.我的AST目前遵循该语言的语义:
type expr = Plus of string*expr*expr | Int of int | ...
type command = While of boolexpr*block | Assign of ...
type block = Commands of command list
...
Run Code Online (Sandbox Code Playgroud)
现在的问题是树中的节点是不同类型的.理想情况下,我会将一个处理节点的函数传递给访问过程; 该过程将打开节点的类型并相应地进行工作.现在,我必须为每个节点类型传递一个函数,这似乎不是最佳解决方案.
在我看来,我可以(1)真正采用这种方法或(2)上面只有一种类型.通常的方法是什么?也许用OO?
ocaml functional-programming abstract-syntax-tree visitor-pattern
在实现访问者模式时,向 Accept 和 Visit 方法添加额外的参数是不是一个坏主意?我从未见过任何这样做的例子,但也没有提到这是一个坏主意。
我想在我的域模型中使用此模式,但是需要附加参数以及实体本身。
例如——
public interface ISomethingVisitor
{
void Visit(Foo foo, int p1, int p2);
}
public interface ISomethingVisitable
{
void Accept(ISomethingVisitor visitor, int p1, int p2);
}
Run Code Online (Sandbox Code Playgroud) 首先,抱歉,如果这是重复的。但我没有看到任何类似的东西。
我熟悉访问者模式,并且正在尝试为图表上的访问者添加更多的灵活性。如果我有节点类 A、B、C、SubB(继承 B),我希望能够有一个接受 B 节点的访问者,并且将自动接受 SubB 节点而不知道它们(定义accept())。
明显的好处是我可以整天进行子类化,并且访问者不需要关心为这些类型定义访问。
我有代码和结果要在下面演示。如您所见,以下是它将访问的节点。
Run Code Online (Sandbox Code Playgroud)new Node(), new ANode(), new BNode(), new CNode(), new BNode(), new SubBNode()
基本上 CountVisitor 正确地报告它发现了 2 个 B,我明白为什么。CountVisitor.visit(SubB&) 不会被覆盖,而是会重定向到 Visitor.visit(SubB&),从而跳过计数。然而,我想要它报告 3 ( 2 Bs + 1 SubB ) 的功能,因为 SubB “是一个” B。我已经考虑过这一点,但我只是不知道如何让类型系统做到这一点。我应该如何重新安排事物以实现该功能?如果保持“是”关系,我也愿意接受替代模式,但我确实认为如果这个障碍得到解决,访问者将是完美的。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Visitor;
class Node
{
public:
vector<Node*> children;
virtual void accept(Visitor&);
};
class ANode : public Node
{
public:
virtual void accept(Visitor&);
};
class BNode : public Node
{ …Run Code Online (Sandbox Code Playgroud) 假设我想编写一个小型解释器,可以使用二元运算
Plus、一元运算Negate和整数常量来计算表达式。
我目前只对 AST 的解释感兴趣,因此为了简单起见,让我们跳过标记化和解析。
在 Haskell 中,有一种或多或少规范的方法来做到这一点:
data Ast = Plus Ast Ast | Negate Ast | IntConst Int
ev :: Ast -> Int
ev (Plus a b) = (ev a) + (ev b)
ev (Negate x) = - (ev x)
ev (IntConst i) = i
main = print $ show $ ev $ (Plus (IntConst 50) (Negate $ IntConst 8))
Run Code Online (Sandbox Code Playgroud)
现在,Python 3.6 似乎没有代数数据类型。我的问题是似乎有很多可能的解决方法。最明显的一个是使用isinstance:
class Plus:
def __init__(self, first, second):
self.first = first
self.second …Run Code Online (Sandbox Code Playgroud) python monkeypatching visitor-pattern algebraic-data-types python-3.x
我知道JavaParser在 AST 上运行,但我很好奇是否可以在与另一条语句相同的行上添加新语句。让我举一个例子来说明我想要实现的目标。
输入示例X.java(不要介意“逻辑”):
public class X {
public static void main(String[] args) {
int a = 1;
while(a < 100) {
a *= 2;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我想要实现的是在System.out.println("End of loop reached");每个循环体的末尾添加语句 - 但是,如果可能的话,我想在循环体中的最后一个语句旁边添加这个新语句。因此,结果应该如下所示:
public class X {
public static void main(String[] args) {
int a = 1;
while(a < 100) {
a *= 2; System.out.println("End of loop reached");
}
}
}
Run Code Online (Sandbox Code Playgroud)
目前我使用以下访问者(用 Kotlin 编写),只是为了了解 JavaParser。然而,这会导致为打印语句添加新行。关于如何指示 JavaParser 在同一行添加新节点有什么想法吗?
class WhileVisitor : VoidVisitorAdapter<Void>() …Run Code Online (Sandbox Code Playgroud) java abstract-syntax-tree visitor-pattern javaparser code-transformation
我有以下设置:
class IVisitor{
public:
virtual SomeType visit(IVisitable& visitable) = 0;
};
class IVisitable{
public:
virtual SomeType accept(IVisitor& visitor) = 0;
};
class ConcreteVisitor : public IVisitor{
public:
SomeType visit(IVisitable& visitable) override {
return calculateSomeStuff();
}
};
class ConcertVisitable : public IVisitable{
public:
SomeType accept(IVisitor& visitor) override {
return visitor.visit(*this);
}
};
Run Code Online (Sandbox Code Playgroud)
但我希望不同的访问者返回不同的类型。为此,IVisitable::accept()还应该返回不同的类型。
这将导致以下(不正确)代码:
template <typename R>
class IVisitor{
public:
virtual R visit(IVisitable& visitable) = 0;
};
class IVisitable{
public:
template <typename R>
virtual R accept(IVisitor<R>& visitor) = 0; …Run Code Online (Sandbox Code Playgroud) visitor-pattern ×10
c++ ×4
c# ×2
inheritance ×1
java ×1
javaparser ×1
ocaml ×1
python ×1
python-3.x ×1
stl ×1
swift ×1
swift2 ×1
templates ×1