gpt4 book ai didi

c++ - CRTP vs 过载和最终

转载 作者:行者123 更新时间:2023-11-30 02:51:55 24 4
gpt4 key购买 nike

我经常使用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 编译器可以优化代码以消除虚函数调用的开销。

因此在上面的示例中,可以删除 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 查找,因为它拥有所有必要的信息。不过,我认为这并不能保证。如果没有 final,vtable 查找仍然是必要的,因为 d 可能指向从 Derived 派生的东西,它还有 foo_impl() 的另一个实现。

关于c++ - CRTP vs 过载和最终,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19363884/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com