编造一个虚拟模板函数C ++ [英] Faking a virtual templated function c++

查看:99
本文介绍了编造一个虚拟模板函数C ++的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我认识到,虚拟模板功能不是在C ++不允许。因为我的特殊应用领域,我们处理的算法集(自然,通过多态和继承的实现),需要强制执行的通用接口。特定算法类工作在迭代器(不奇怪),但我们想假虚拟化通过这些模板功能。这是我们与使用boost :: MPL想出了一个解决方案的一个例子。我意识到这是漫长的,但是这是我可以创建模拟什么,我瞄准了一个最小的code例子。在code后,我的具体问题如下:

I realize that virtual template functions are not allowed in c++. Because of my specific application domain, we deal with sets of algorithms (natural for implementation through polymorphism and inheritance) and need to enforce a common interface. Particular algorithmic classes work over iterators (not surprising), however we would like to fake virtualization through these templated functions. Here is an example of a solution we came up with using boost::mpl. I realize this is lengthy, but this is a minimal code example that I could create to simulate what I am aiming for. My specific question follows after the code.

#include <iostream>
#include <vector>
#include <boost/mpl/list.hpp>
#include <boost/mpl/for_each.hpp>

using namespace std;

class A;
class B;
class C;

typedef boost::mpl::list<B, C> DerivedClassList; 

template<typename Base, typename Iterator>
struct VirtualFunc{
  public:
    VirtualFunc(Base* _memory, Iterator _begin, Iterator _end) : 
      m_memory(_memory), m_begin(_begin), m_end(_end){}

    template<typename T>
      void operator()(T& _t) {
        T* tptr = dynamic_cast<T*>(m_memory);
        if(tptr != NULL){
          tptr->Print(m_begin, m_end);
        }   
      }   

  private:
    Base* m_memory;
    Iterator m_begin, m_end;
};  

class A{
  public:
    A(){}
    virtual ~A(){}

    template<typename Iterator>
      void Print(Iterator _begin, Iterator _end){
        boost::mpl::for_each<DerivedClassList>(VirtualFunc<A, Iterator>(this, _begin, _end));
      }   
};  

class B : public A {
  public:
    B(){}
    virtual ~B(){}

    template<typename Iterator>
      void Print(Iterator _begin, Iterator _end){
        cout << "Begin::" << *_begin << endl;
      }
};

class C : public A {
  public:
    C(){}
    virtual ~C(){}

    template<typename Iterator>
      void Print(Iterator _begin, Iterator _end){
        for(Iterator it = _begin; it!=_end; it++)
          cout << "Iterator::" << *it << endl;
      }
};

int main(){
  vector<size_t> numbers;
  for(size_t i = 0; i<5; i++)
    numbers.push_back(i);

  A* printBegin = new B();
  A* printAll = new C();
  //faking virtualism will print just begin
  printBegin->Print(numbers.begin(), numbers.end());
  //faking virtualism will print all
  printAll->Print(numbers.begin(), numbers.end());
}

那么,什么是这个假虚模板函数的陷阱?有没有更好更简洁的方式来做到这一点?

So what is the pitfalls of this "fake virtual" templated functions? Is there a better more concise way to do this?

此外借口code类标准,它们是什么,我们在使用我的工作场所。

Also excuse the code standards, they are what we use at my workplace.

推荐答案

为什么不与经典的双模式调度更换。看来你知道在基础层面的类层次结构 - 所以我会用以下内容。这是众所周知的,访客或DoubleDispatch图案和消除非有效的dynamic_cast。坦率地说 - 如果我看到的dynamic_cast&LT;>我总是想着双调度,

Why not replace with classic double dispatch pattern. It seems that you know your class hierarchy at the base level - so I would use the following. It is well known, Visitor or DoubleDispatch pattern and eliminate the non efficient dynamic_cast. Frankly - if I see dynamic_cast<> I always think about double-dispatch,

已知clasees:

class A;
class B;
class C;

虚拟主义的起点:

Start point of virtual-ism:

class IVirtualFunc {
  public:
    virtual void callFor(B& memory) = 0;
    virtual void callFor(C& memory) = 0;
};  

有关模板参数执行:

template<typename Iterator>
class VirtualFunc : public IVirtualFunc {
  public:
    VirtualFunc (Iterator _begin, Iterator _end) : begin(_begin), end(_end) {}
    virtual void callFor(B& memory);
    virtual void callFor(C& memory);
  private:
    Iterator begin;
    Iterator end;   
};

实际实现的抽象基类:

The abstract base class for the actual implementations:

class A{
  public:
    template<typename Iterator>
    void Print(Iterator _begin, Iterator _end) {
        VirtualFunc<Iterator> vFunc(_begin, _end);
        dispatch(vFunc);   
    }
    virtual void dispatch(IVirtualFunc&) = 0;   
};  

与它( VirtualFunc&LT;&迭代器GT; :: callFor(B和b))双重分派第一实际执行情况:

First actual implementation with double dispatch for it (VirtualFunc<Iterator>::callFor(B& b)):

class B : public A {
  public:
    B(){}
    virtual ~B(){}

    template<typename Iterator>
      void Print(Iterator _begin, Iterator _end){
        cout << "Begin::" << *_begin << endl;
      }
    virtual void dispatch(IVirtualFunc& vf) { vf.callFor(*this); }   
};

template<typename Iterator>
void VirtualFunc<Iterator>::callFor(B& b)
{
     b.Print(begin, end);
}

与它( VirtualFunc&LT;&迭代器GT; :: callFor(C和C))双重派遣第二实际执行情况:

Second actual implementation with double dispatch for it (VirtualFunc<Iterator>::callFor(C& c)):

class C : public A {
  public:
    C(){}
    virtual ~C(){}

    template<typename Iterator>
      void Print(Iterator _begin, Iterator _end){
        for(Iterator it = _begin; it!=_end; it++)
          cout << "Iterator::" << *it << endl;
      }
    virtual void dispatch(IVirtualFunc& vf) { vf.callFor(*this); }   
};
template<typename Iterator>
void VirtualFunc<Iterator>::callFor(C& c)
{
     c.Print(begin, end);
}

和它的作品证明:

int main(){
  vector<size_t> numbers;
  for(size_t i = 0; i<5; i++)
    numbers.push_back(i);

  A* printBegin = new B();
  A* printAll = new C();
  //faking virtualism will print just begin
  printBegin->Print(numbers.begin(), numbers.end());
  //faking virtualism will print all
  printAll->Print(numbers.begin(), numbers.end());
}

OUTPUT:

OUTPUT:

Begin::0
Iterator::0
Iterator::1
Iterator::2
Iterator::3
Iterator::4

这篇关于编造一个虚拟模板函数C ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆