我可以使用字体表构建抽象访问者吗?
Can I build an abstract visitor using a typelist?
所以我有一个抽象类,它是任何使用对象集合的访问者的基础:
class visitor
{
virtual void visit(foo) = 0;
virtual void visit(bar) = 0;
virtual void visit(baz) = 0;
virtual void visit(quux) = 0;
};
但是我也将所有这些类型保存在boost::mpl::list
中:
using type_list = boost::mpl::list<
foo,
bar,
baz,
quux
>;
每当我添加新类型时,都必须更新访问者类似乎是一种耻辱......有什么方法可以通过传递type_list
来自动生成访问者类?
std::enable_if
和boost::mpl::find
似乎是要走的路,但我不能模板化虚拟方法,不是吗?
不能使用可变参数模板虚拟方法,但可以模板化基类:
template<class T> class singleVisitorBase { virtual void visit(T) = 0; };
template<class list> class visitor;
template<class... Ts> class visitor<boost::mpl::list<Ts...>>
: singleVisitorBase<Ts>... {};
另一种方法是使用递归继承:
template<class list> class visitor;
template<> class visitor<boost::mpl::list<>> {};
template<class T, class... Ts> class visitor<boost::mpl::list<T, Ts...>>
: singleVisitorBase<T>, visitor<boost::mpl::list<Ts...>> {};
但是,我更喜欢单级多重继承,因为它会产生更干净的类型层次结构,这些层次结构更易于在调试器中检查。
在这两种情况下,都会有一些空间开销,因为visitor
将包含n
vtable 指针到其 vtable,以允许投射到基类型。空间开销较少但编译时开销较大的替代方法是使用 Boost.Preprocessor 通过 BOOST_PP_REPEAT
生成长度n
的类体:
template<class list, std::size_t N> class visitorImpl;
#define VISITOR_MAX 32
#define VISITOR_VISIT(z,I,_)
virtual void visit(typename boost::mpl::at<list, I>::type) = 0;
#define VISITOR_CLASS(z,N,_)
template<class list>
class visitorImpl<list, N>
{
BOOST_PP_REPEAT(N, VISITOR_VISIT, )
};
BOOST_PP_REPEAT(VISITOR_MAX, VISITOR_CLASS, )
template<class list> using visitor
= visitorImpl<list, typename boost::mpl::size<list>::type::value>;
相关文章:
- 访问者访问变体并返回不同类型时出错
- 无法创建抽象类的实例
- 如何定义一个纯抽象基类
- 派生类是否可以在抽象工厂设计模式中具有数据成员
- 用pybind11包装C++抽象类时出错
- 如何处理从一个对象传递到另一个在C++中具有公共抽象类的对象的消息
- 有没有办法按值将纯抽象类的所有子类传递给 C++ 中的函数?
- 抽象类错误,请参阅声明" "是抽象的
- 将自定义函数传递到基抽象类中以延迟执行
- 命名参数习惯用法和(抽象)基类
- 打印抽象对象 c++
- 如何在从抽象基派生的类中实现相同的方法?
- 将包含抽象类和普通类C++包导出到 Python
- C++:处理抽象类中的错误时出现问题
- C ++如何在原始抽象类中创建一个函数,该函数接受派生类的输入
- C++抽象的字节序是中立的吗?
- 在 C++ 中使用另一个头文件中的抽象类
- ATL::CComContainedObject<contained>: C2259 无法实例化抽象类
- C++:从抽象类重写纯虚拟运算符重载
- 我可以使用字体表构建抽象访问者吗?