C++ 在现代C+中定义内联访问者+;交替服用
我发现了一篇非常有趣的文章 不过,提出的解决方案相当复杂 我想知道是否有更简单的方法来解决这个问题 下面添加了代码和示例,以避免需要遵循链接 以论文中的示例为例,给出以下类别:C++ 在现代C+中定义内联访问者+;交替服用,c++,c++11,design-patterns,C++,C++11,Design Patterns,我发现了一篇非常有趣的文章 不过,提出的解决方案相当复杂 我想知道是否有更简单的方法来解决这个问题 下面添加了代码和示例,以避免需要遵循链接 以论文中的示例为例,给出以下类别: struct Triangle; struct Square; struct PolygonVisitor { virtual ~PolygonVisitor() {} virtual void visit(Triangle& tr) = 0; virtual void visit(S
struct Triangle;
struct Square;
struct PolygonVisitor
{
virtual ~PolygonVisitor() {}
virtual void visit(Triangle& tr) = 0;
virtual void visit(Square& sq) = 0;
};
struct Polygon
{
virtual void accept(PolygonVisitor& v) = 0;
};
struct Triangle : Polygon
{
void accept(PolygonVisitor& v) override
{
v.Visit(*this);
}
};
struct Square : Polygon
{
void accept(PolygonVisitor& v) override
{
v.Visit(*this);
}
};
一个内联访问者被构造并用于计算一个
形状有:
int CountSides(Polygon& p)
{
int sides = 0;
auto v = begin_visitor<PolygonVisitor>()
.on<Triangle>([&sides](Triangle& tr)
{
sides = 3;
})
.on<Square>([&sides](Square& sq)
{
sides = 4;
})
.end_visitor();
p.Accept(v);
return sides;
}
int CountSides(多边形和多边形)
{
内边=0;
自动v=开始\访客()
.在([&边](三角形和tr)
{
侧面=3;
})
.在([&边](正方形和正方形)
{
侧面=4;
})
.end_visitor();
p、 接受(v);
返回侧;
}
内联访问者的定义如下(代码取自
):
模板
类组合器
{
公众:
类InnerVisitor:public BaseInnerVisitor
{
公众:
使用BaseInnerVisitor::Visit;
typedef typename BaseInnerVisitor::VisitorInterface VisitorInterface;
InnerVisitor(ArgsT&&args)
:BaseInnerVisitor(std::move(args.second)),m_f(std::move(args.first))
{
}
无效访问(T&T)决赛
{
VisitImpl(t);
}
私人:
模板
typename std::启用\u如果<
std::is_assignable::value>::类型
VisitImpl(T&T)
{
m_f(t);
}
模板
typename std::enable_if::value>::type
VisitImpl(T&T)
{
m_f(t,*此);
}
F m_F;
};
组合浏览器(ArgsT&&args):m_args(std::move(args))
{
}
模板
分频器
打开(Fadd&f)&&
{
回程分频器(
std::make_pair(std::move(f),std::move(m_args));
}
模板
typename std::enable_if::value,
InnerVisitor>::类型
(完)&&
{
返回InnerVisitor(std::move(m_args));
}
ArgsT m_args;
};
模板
类空视野器
{
公众:
类InnerVisitor:公共TVisitorBase
{
公众:
使用TVisitorBase::Visit;
typedef TVisitorBase访问接口;
InnerVisitor(std::nullptr\t)
{
}
};
模板
分频器
打开(Fadd&f)&&
{
回程分频器(
std::make_pair(std::move(f),nullptr));
}
};
模板
清空访问者开始\访问者()
{
返回EmptyVisitor();
}
解决此问题的一种可能方法是从抽象访问者(示例中为PolygonVisitor)继承一个新类(InlineVisitor),该类在其构造函数中为它必须实现的每个抽象方法接收一个std::函数 每个抽象方法都是根据存储的std::函数来实现的
#include <functional>
#include <iostream>
struct Triangle;
struct Square;
struct PolygonVisitor
{
virtual ~PolygonVisitor() {}
virtual void visit(Triangle& tr) = 0;
virtual void visit(Square& sq) = 0;
};
struct Polygon {
virtual void accept(PolygonVisitor& v) = 0;
};
struct Triangle : Polygon
{
void accept(PolygonVisitor& v) override { v.visit(*this); }
};
struct Square : Polygon
{
void accept(PolygonVisitor& v) override { v.visit(*this); }
};
class InlineVisitor : public PolygonVisitor
{
public:
virtual void visit(Triangle& value) { triangleFx_(value); }
virtual void visit(Square& value) { squareFx_(value); }
std::function<void(Triangle&)> triangleFx_;
std::function<void(Square&)> squareFx_;
InlineVisitor(const std::function<void(Triangle&)> triangleFx,
const std::function<void(Square&)> squareFx)
: triangleFx_(triangleFx)
, squareFx_(squareFx) {}
};
int countSides(Polygon& p)
{
int sides = 0;
InlineVisitor countSidesVisitor([&sides](Triangle& tr) { sides = 3; },
[&sides](Square& sq) { sides = 4; });
p.accept(countSidesVisitor);
return sides;
}
int main(int argc, char *argv[])
{
Triangle t;
Square s;
std::cout << "sides of Triangle: " << countSides(t) << std::endl
<< "sides of Square: " << countSides(s) << std::endl;
return 0;
};
#包括
#包括
结构三角形;
结构广场;
结构PolygonVisitor
{
虚拟~PolygonVisitor(){}
虚拟无效访问(三角形和tr)=0;
虚拟无效访问(平方和平方)=0;
};
结构多边形{
虚拟无效接受(PolygonVisitor&v)=0;
};
结构三角形:多边形
{
void accept(PolygonVisitor&v)重写{v.visit(*this);}
};
结构正方形:多边形
{
void accept(PolygonVisitor&v)重写{v.visit(*this);}
};
类InlineVisitor:公共PolygonVisitor
{
公众:
虚拟无效访问(三角形和值){triangleFx_ux(值);}
虚拟虚空访问(平方和值){squareFx_uz(值);}
std::函数triangleFx;
std::函数squareFx;
InlineVisitor(const std::函数triangleFx,
常量std::函数squareFx)
:triangleFx_Ux(triangleFx)
,squareFx_u2;(squareFx){}
};
整数边(多边形和多边形)
{
内边=0;
InlineVisitor countSidesVisitor([&sides](三角形&tr){sides=3;},
[&sides](正方形和正方形){sides=4;});
p、 接受(countSidesVisitor);
返回侧;
}
int main(int argc,char*argv[])
{
三角形t;
正方形s;
std::不能将相关上下文添加到您的问题中。不要指望您的听众点击此处的链接。我很想了解生成的汇编程序与手写访问者的比较。我们在设计中添加的复杂性都是为了消除生成的汇编程序的差异。
#include <functional>
#include <iostream>
struct Triangle;
struct Square;
struct PolygonVisitor
{
virtual ~PolygonVisitor() {}
virtual void visit(Triangle& tr) = 0;
virtual void visit(Square& sq) = 0;
};
struct Polygon {
virtual void accept(PolygonVisitor& v) = 0;
};
struct Triangle : Polygon
{
void accept(PolygonVisitor& v) override { v.visit(*this); }
};
struct Square : Polygon
{
void accept(PolygonVisitor& v) override { v.visit(*this); }
};
class InlineVisitor : public PolygonVisitor
{
public:
virtual void visit(Triangle& value) { triangleFx_(value); }
virtual void visit(Square& value) { squareFx_(value); }
std::function<void(Triangle&)> triangleFx_;
std::function<void(Square&)> squareFx_;
InlineVisitor(const std::function<void(Triangle&)> triangleFx,
const std::function<void(Square&)> squareFx)
: triangleFx_(triangleFx)
, squareFx_(squareFx) {}
};
int countSides(Polygon& p)
{
int sides = 0;
InlineVisitor countSidesVisitor([&sides](Triangle& tr) { sides = 3; },
[&sides](Square& sq) { sides = 4; });
p.accept(countSidesVisitor);
return sides;
}
int main(int argc, char *argv[])
{
Triangle t;
Square s;
std::cout << "sides of Triangle: " << countSides(t) << std::endl
<< "sides of Square: " << countSides(s) << std::endl;
return 0;
};