C ++ - & CRTP)。类型擦除与多态性 [英] C++ -& CRTP . Type erasure vs polymorphism
问题描述
好的,我们去。我尝试使用 CRTP 模板,以便从我的应用中删除多态性的需要。我使用类似下面的aproach
template< RealType> class Base
{
void doSomething()
{
static_cast< RealType>(this) - > doSomethingImpl()
}
class Derived1:public Base
{
void doSomethingImpl()
{
/ * do something,for real * /
}
}
class Derived2:public Base
{
void doSomethingImpl()
{
/ * do something else * /
}
}
这个aproach,如果我理解正确,允许我的类没有vtable,是直接的,不需要额外的间接。
现在想象我要把所有的Derived#类存储在容器中。让我们说一个向量。
第一种方法:我可以创建一个非模板SuperBase类,Base从该类继承并存储在容器中。
然而在我看来,如果我想这样做,我必须在SuperBase中做doSomething虚拟。我的目标主要是没有一个vtable。
第二种方法:我使用类型擦除,例如boost :: any来存储我的元素。
但是,我没有看到一个方法,我可以迭代的元素,并调用doSomething对他们,因为使用boost ::任何,我需要知道对象的实际类型,当迭代。 / p>
你认为我想做的是甚么可能?
似乎是因为doSomething()是Base的一部分,但除了使用继承,我看不到一个方法来做。 p>
我的目标主要是没有一个vtable。
如果你想要这个,除非你实现你自己的虚拟调度系统(这可能会低于编译器做的) ,你被困于模板,也就是编译时多态性。正如名称所示,为了使用它, 一切都必须在编译时知晓 。如果您需要根据运行时事件(例如用户输入)进行决策, 您想要运行时多态性 。
我不禁要问:为什么要避免vtables?如果你是这样决定的,为什么你不是在C编程?)
OK here we go. I'm trying to use the CRTP template in order to remove the need of polymorphism from my app. I use an aproach like the one bellow
template <RealType> class Base
{
void doSomething()
{
static_cast<RealType>(this)->doSomethingImpl()
}
class Derived1 : public Base
{
void doSomethingImpl()
{
/* do something, for real */
}
}
class Derived2 : public Base
{
void doSomethingImpl()
{
/* do something else */
}
}
This aproach, if I understood correctly, allows my classes to have no vtable, so function calls are direct and don't require the extra indirection.
Now imagine I want to store all my Derived# classes in a container. Let's say a vector.
First approach : I can create a non-template SuperBase class from which Base inherits and store that in the container.
However it seems to me that if I want to do that, I will have to make doSomething virtual, in SuperBase. And my goal is mainly not to have a vtable.
Second approach : I use type erasure, i.e. something like boost::any to store my elements in the Vector. But then, I don't see a way I can iterate over the elements and call doSomething on them, because to "use" boost::any, I need to know the real type of the object when iterating.
Do you think what I want to do is even possible ?
Seems to me that it is because doSomething() is part of Base but except using inheritance, I can't see a way to do it ....
And my goal is mainly not to have a vtable.
If you want this, then, unless you implement your own virtual dispatch system (which would likely be inferior to what the compiler does), you're stuck with templates, a.k.a. compile-time polymorphism. And as the name says, in order to use this, everything must be known at compile-time. If you need to make decisions based on runtime events (like, e.g., user input), you want runtime polymorphism.
I can't help but have to ask: Why do you want to avoid vtables? (And if you're so determined, why aren't you programming in C?)
这篇关于C ++ - & CRTP)。类型擦除与多态性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!