我通过CRTP创建了一个利用静态多态的类层次结构:
class VirtualBaseData {public: //someVirtualFunction}template<typename Derived>class BaseData<Derived> {public: template<typename Visitor> voID accept(Visitor &v){ static_cast<Derived*>(this)->accept(v); }}class DerivedBaseData1: BaseData<DerivedBaseData> {public: template<typename Visitor> voID accept(Visitor &v){ //Specific implementation } }class DerivedBaseData2: BaseData<DerivedBaseData> {public: template<typename Visitor> voID accept(Visitor &v){ //Specific implementation } }
我想将DerivedBaseData存储在一个包含中,以便以后迭代和访问.
int main(){ std::vector<VirtualBaseData*> dataSet; dataSet.push_back(new DerivedBaseData1); dataSet.push_back(new DerivedBaseData2); for(auto it = fifth.begin(); it != fifth.end(); ++it){ it->accept(); //Error: VirtualBaseData does not have a member function accept }}
我正在寻找一种方法来将静态访问者与静态多态性层次结构相结合.
我需要一个静态多态的VirtualBaseData类,它不是模板类,以便在容器中使用类.
但是,由于我不能将VirtualBaseData类作为模板类,因此我无法像在CRTPattern中那样为派生类创建适当的static_cast.
我的问题是:有没有人有一个好的策略,可以保留我的静态多态设置以及静态访问者模式?
供参考:我已经实现了我的静态访问者,如第27-23页http://hillside.net/plop/2006/Papers/Library/portableProgrammingPL.pdf所述
解决方法 如果你不知道你的对象在编译时会有多少/什么类型,那么它就是动态多态的一个用例(至少,我不知道如何只使用静态多态).但是……如果您在编译时知道对象的确切数量和类型,现在我们正在谈论!这是一个最小的编译示例(code on ideone):
#include <iostream>#include <tuple>#include <type_traits>using namespace std;template<typename Derived>class BaseData {public: template<typename Visitor> voID accept(Visitor &v){ static_cast<Derived*>(this)->accept(v); }};class DerivedBaseData1: BaseData<DerivedBaseData1> {public: template<typename Visitor> voID accept(Visitor &v){ std::cout << "DerivedBaseData1: accepting visitor " << v << std::endl; } };class DerivedBaseData2: BaseData<DerivedBaseData2> {public: template<typename Visitor> voID accept(Visitor &v){ std::cout << "DerivedBaseData2: accepting visitor " << v << std::endl; } };namespace impl { template <size_t N> struct num2type {}; template <size_t IDx,typename T,typename Visitor> voID accept_impl(Visitor &v,T &&collection,num2type<IDx>) { // run accept on current object auto &object = std::get<IDx>(collection); object.accept(v); // move iteration forward accept_impl(v,std::forward<T>(collection),num2type<IDx - 1>{}); } template <typename T,num2type<0>) { // run accept on current object auto &object = std::get<0>(collection); object.accept(v); }}template<typename ...Ts,typename Visitor>voID accept(Visitor &v,std::tuple<Ts...> &&collection) { using T = decltype(collection); impl::accept_impl(v,impl::num2type<std::tuple_size<std::decay_t<T>>::value - 1>{});}int main() { using visitor_type = int; visitor_type visitor = 42; DerivedBaseData1 a1,a3; DerivedBaseData2 a2; accept(visitor,std::tIE(a1,a2,a3)); return 0;}
使用静态多态性,您可以迭代静态集合(此处为std :: tuple),并在每个集合上使用所需的参数调用所需的方法.
总结以上是内存溢出为你收集整理的c – 将静态访问者与静态多态性层次结合起来全部内容,希望文章能够帮你解决c – 将静态访问者与静态多态性层次结合起来所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)