伪造虚拟模板化函数 c++

Faking a virtual templated function c++

本文关键字:函数 c++ 虚拟 伪造      更新时间:2023-10-16

我意识到 c++ 中不允许使用虚拟模板函数。由于我的特定应用领域,我们处理算法集(自然是通过多态性和继承实现的),并且需要强制执行通用接口。特定的算法类在迭代器上工作(这并不奇怪),但是我们希望通过这些模板化函数来伪造虚拟化。以下是我们使用boost::mpl提出的解决方案示例。我意识到这很长,但这是一个最小的代码示例,我可以创建它来模拟我的目标。我的具体问题在代码之后。

#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());
}

那么这种"假虚拟"模板化函数的陷阱是什么呢?有没有更好更简洁的方法可以做到这一点?

请原谅代码标准,它们是我们在工作场所使用的。

为什么不替换为经典的双调度模式。您似乎知道基础级别的类层次结构 - 所以我会使用以下方法。众所周知,访客或双调度模式消除了低效dynamic_cast。坦率地说 - 如果我看到dynamic_cast<>我总是想到双重调度,

已知扣:

class A;
class B;
class C;

虚拟主义的出发点:

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;   
};

实际实现的抽象基类:

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<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<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());
}

输出:

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