[英]Faking a virtual templated function c++
我意識到在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());
}
那么,這種“偽虛擬”模板函數的陷阱是什么? 有沒有更好,更簡潔的方法來做到這一點?
還請原諒代碼標准,它們是我們在工作場所使用的標准。
為什么不替換為經典的雙重調度模式。 看來您知道基本級別的類層次結構-因此,我將使用以下內容。 眾所周知,Visitor或DoubleDispatch模式並消除了無效的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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.