簡體   English   中英

CRTP vs過載和最終

[英]CRTP vs overload and final

我經常使用CRTP從基類調用派生類函數。 它具有不會產生虛擬函數調用成本的好處,例如:

template< class Derived >
class Base
{
public:
   void foo() 
   {
      static_cast<Derived*>(this)->foo_impl(); // Non virtual derived class call
   }
};

class Derived : public Base<Derived> 
{
private:
   void foo_impl() 
   {
      // Do Stuff
   } 
};

C ++ 11引入了final語言標識符,它將虛函數(或類)標記為final,告訴編譯器將不再進一步覆蓋該函數。

我的理解(來自Going Native 2013演示文稿)如果虛擬函數被標記為final則編譯器可以優化代碼以消除虛函數調用的開銷。

Ergo在上面的示例中,可以刪除CRTP並且仍然避免虛函數調用的開銷,前提是派生類將虛函數標記為final即:

class Base
{
public:
   virtual void foo_impl() = 0;

   void foo() 
   {
      foo_impl(); // Non virtual derived class call
   }
};

class Derived : public Base 
{
public:
   // function marked as final, no virtual function call overhead
   virtual void foo_impl() final   
   {
      // Do Stuff
   } 
};

如果是這種情況,是否有任何建議,哪種方法最好?

CRTP是否仍然是首選,因為它保證函數調用是非虛擬的,而基於final優化不能依賴?

這取決於你如何傳遞實例。 考慮在一個翻譯單元:

Derived d;
foo( &d );

在另一個:

void foo( Base* b )
{
    b->foo();
}

除LTO外,編譯器沒有機會刪除虛擬調用開銷。

如果是OTOH,你有:

void foo( Derived* d )
{
    d->foo();
}

編譯器現在可以足夠聰明,可以優化vtable查找,因為它具有所有必要的信息。 不過,我認為這不是保證。 沒有最終,vtable查找仍然是必要的,因為d可以指向從Derived東西,它還有另一個foo_impl()

我的5點:

當類名已知時,最近的GCC優化虛函數。

此外,標准說如果類名已知,則可以內聯虛擬功能 - 例如,沒有虛擬分派。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM