问题描述
我认识到,虚拟模板功能不是在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 ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!