【发布时间】:2016-08-07 18:50:50
【问题描述】:
我正在使用访问者模式来实现反射,而不依赖于 RTTI。 我的问题是:
我想实现一个访问者,它可以将派生自同一个 BaseItem 类的不同类 DerivedItem1、DerivedItem2 等转换为这个 BaseItem 类。
基类和其中一个派生类如下所示:
class BaseItem : public AbstractItem
{
virtual ~BaseItem(){}
virtual void visit(AbstractVisitor &v)
{
v.handle(*this);
}
}
class DerivedItem1 : public BaseItem
{
virtual ~DerivedItem(){}
virtual void visit(AbstractVisitor &v)
{
v.handle(*this);
}
}
访问者类:
class BaseVisitor : public AbstractVisitor
{
virtual ~BaseVisitor(){}
void handle(BaseItem &item)
{
// <-- stuff to do for all classes derived from BaseItem
}
}
不可能像这样实现 BaseVisitor,
因为DerivedItem::visit(BaseVisitor) 不会将自己转换为它的基类
并且BaseVisitor::handle(BaseItem &v) 永远不会被调用。
我想将访问者实现为模板类,将基类和所有派生类作为模板参数,如下所示:
template <typename BaseT, typename... DerivedT>
class BaseVisitor : public AbstractVisitor
{
public:
virtual ~BaseVisitor(){}
// unpacking all DerivedT should happen here
// DerivedT_X are the packed template arguments ...DerivedT
void handle(DerivedT_1 &item)
{
// <-- cast item to BaseT, do stuff, return BaseT* to caller
}
void handle(DerivedT_2 &item)
{
// <-- cast item to BaseT, do stuff, return BaseT* to caller
}
};
是否有可能使用 C++ 让编译器自行生成此成员函数?
【问题讨论】:
-
您可以从可变参数模板类型中获取
std::tuple和iterate over this。 -
IINM,Andrei Alexandrescu 在Modern C++ Design 中有一个关于此的章节。请参阅this link 了解类似情况。
-
@AmiTavory 啊,很有创意。 Andrei 真的很擅长那种模板元编程的东西。
-
我相信 OP 是在询问他是否可以在模板定义中而不是在函数体中解压缩 argpack。
标签: c++ variadic-templates template-classes