简体   繁体   English

为什么我要在 static 多态性的简单模板上使用 CRTP?

[英]Why do I want to use CRTP over simple template for static polymorphism?

I have read a lot of posts about Curiously Recurring Template Pattern and I still do not see why I do not want to use it over just using template programming.我已经阅读了很多关于Curiously Recurring Template Pattern的帖子,但我仍然不明白为什么我不想使用它而不是仅仅使用模板编程。

Below is an example slightly modified from Wikipedia:下面是一个从 Wikipedia 稍作修改的示例:

template <class T> 
struct Base
{
    void interface()
    {
        static_cast<T*>(this)->implementation();
    }
};

struct Derived : Base<Derived>
{
    void implementation();
};

However, I can do exactly the same with just template in a more straightforward way:但是,我可以用更直接的方式对模板做同样的事情:

template <class T> 
struct OuterClass
{
    void interface()
    {
        nested->implementation();
    }
private:
    T* nested;
};

struct NestedClass
{
    void implementation();
};

OuterClass<NestedClass> x;
x.interface();

What's the advantage of CRTP over my implementation? CRTP 与我的实施相比有什么优势?

Edit: the line T* nested;编辑:线T* nested; as member variable can also be just T nested; as 成员变量也可以只是T nested; so that nested is created by the constructor of outer class.这样nested是由外部 class 的构造函数创建的。

I can do exactly the same我可以做同样的事情

NO, you have an additional data member "T* nested" which is set during runtime.不,您有一个在运行时设置的附加数据成员“T* 嵌套”。 As this, the compiler has not the full knowledge of the exact object it will see and may optimize less optimal.因此,编译器不完全了解它将看到的确切 object,并且可能优化不太优化。 In addition, you have an indirection via pointer which is not the case if you use "this", as the access to any data member is known at compile time, even if the author of a call has to write static_cast<T*>(this)->something , but the full operation is completely known at compile time.此外,如果使用“this”,则可以通过指针进行间接寻址,因为在编译时就知道对任何数据成员的访问,即使调用的作者必须编写static_cast<T*>(this)->something ,但完整的操作在编译时是完全已知的。

What you do is more like a virtual function call than compile time polymorphism.你所做的更像是一个虚拟的 function 调用,而不是编译时多态性。

In addition you also have to set the nested pointer somewhere, which means something passed through the constructor, which is also overhead in code and speed.此外,您还必须在某处设置嵌套指针,这意味着通过构造函数传递的东西,这也是代码和速度的开销。

And at last point I see, you need to create your object in two steps.最后我看到,您需要分两步创建 object。 First the "nested" one and than pass its pointer to the outer class.首先是“嵌套”的,然后将其指针传递给外部 class。 This can also result in performance drop and can have side effects like non contiguous memory, cache line misses and so on.这也可能导致性能下降,并可能产生诸如非连续 memory、缓存行未命中等副作用。

Solutions provided is pretty much a home-brew of virtual functions-based polymorphism (assuming incomplete sample and having some code elsewhere which actually sets T* )提供的解决方案几乎是基于虚函数的多态性的自制(假设样本不完整,并且在其他地方有一些代码实际上设置了T*

The main disadvantage of run-time polymorphism (aka type erasure) is performance.运行时多态性(又名类型擦除)的主要缺点是性能。 Since you need to dereference the pointer, compiler generally has no way of knowing at compile time which function is called, and thus can't inline the function and make decisions on side-effects of the function.由于您需要取消引用指针,编译器通常无法在编译时知道调用了哪个 function,因此无法内联 function 并就 ZC1C425268E68384F14Z 的副作用做出决定On top of that, calling through pointer generally requires an extra step of pointer dereference, which also slows things down.最重要的是,通过指针调用通常需要一个额外的指针取消引用步骤,这也会减慢速度。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM