如何设计围绕模板成员函数不能是虚拟的限制 [英] How to design around the limitation that templated member functions can't be virtual

查看:216
本文介绍了如何设计围绕模板成员函数不能是虚拟的限制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到一个设计问题,在(C ++)我想一个模板成员函数(非模板类)是虚拟的,我想知道是否有一个好的,优雅的方式围绕这个问题。



在这种情况下,我有个机器 处理项目。我使用具有虚拟进程(Item)功能的机器的抽象基类,以便每个机器可以定义他们自己唯一的处理方法。问题是,项目也是通用的,因为它们暴露了某些接口如何处理它们。由于原因(主要是为了性能...没有vtable开销),我想使用编译时多态性这些项目。所以现在每台机器都有一个接口,如:

  class Machine 
{public:
template< ;类型名称T>
virtual void process(T& item)= 0;
};

但是在C ++中这是不可能的,因为模板成员函数不能是虚拟的。肯定我可以使机器类模板上的项目类型T,但这增加了更多的头痛我在更大的设计方案,真的没有其他部分的机器类依赖于Item ...它只是一个参数process()函数。



有一个更好的方法或任何建议,如何提供这种通用家庭的机器,处理一系列通用项目(其中项目使用compile-时间多态性)。



欣赏任何建议

解决方案

div>

通常,使用双调度。

  
class Item {
public:
virtual void bounce(Machine& mach);
};
class Machine {
public:
template< typename T> void process(T& t);
virtual void process(Item& i){
return i.bounce(* this);
}
};
template< typename T> class CRTPItem {
public:
virtual void bounce(Machine& mach){
return mach.process(*(T *)this);
}
};
class ConcreteItem:public CRTPItem< ConcreteItem> {
public:
// blah blah
};

在这种情况下,您不需要整个ConcreteItem接口的虚拟开销, t需要任何共同的东西,只是一个 bounce 函数,它是通过继承自 CRTPItem 自动构建的。这只是两个vtable调用,而不是你原来的,而不是需要一个vtable调用所有的Item的功能,并且接口仍然可以保留所有的强类型,如果你可以创建虚拟模板。 / p>

I'm running into a design issue where (in C++) I'd like a templated member function (of a non-template class) to be virtual and am wondering if there is a good, elegant way around the issue.

The scenario goes, I have machines that process generic items. I use an abstract base class for machines with a virtual process(Item) function so that each machine can define their own unique processing method. The problem is that the items are also "generic" in that they expose certain interfaces for how they can be processed. For reasons (mainly for performance...no vtable overhead), I'd like to use compile-time polymorphism for these items. So that now each machine would have an interface like:

class Machine
{ public:
    template <typename T>
    virtual void process(T& item) = 0; 
};

However this is impossible in C++ as templated member functions cannot be virtual. certainly I can make the machine class templated on the Item type T but this adds more headaches for me in the larger design scheme and really no other part of the Machine class depends on Item...it's only an argument to the process() function.

Is there a better way around this or any suggestions for how to provide this kind of generic family of machines that process a family of generic items (where the items use compile-time polymorphism). Am I off the deep end in terms of my design.

Appreciate any suggestions

解决方案

Typically, double dispatch is used.

class Machine;
class Item {
public:
    virtual void bounce(Machine& mach);
};
class Machine {
public:
    template<typename T> void process(T& t);
    virtual void process(Item& i) {
        return i.bounce(*this);
    }
};
template<typename T> class CRTPItem {
public:
    virtual void bounce(Machine& mach) {
        return mach.process(*(T*)this);
    }
};
class ConcreteItem : public CRTPItem<ConcreteItem> {
public:
    // blah blah
};

In this case, you don't need virtual overhead for the whole ConcreteItem interface, and they don't need anything in common, just that one bounce function which is built for you automatically by inheriting from CRTPItem. This is only two vtable calls as opposed to the one you had originally, as opposed to needing a vtable call for all of Item's functions, and the interface can still retain all strong-typing that it would have if you could create virtual templates.

这篇关于如何设计围绕模板成员函数不能是虚拟的限制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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