CRTP与“派生的”函数中的函数的直接实现对比
我正在尝试更好地了解 CRTP。到目前为止,我的理解是它允许人们编写如下所示的函数。
template <class T>
void foo(Base<T> x ) { x.do_stuff() }
现在,根据传递给函数 foo()
的实际编译时派生对象 x
,它将执行不同的操作。
但是,我可以从 Base
派生类 Derived
,并使用非虚拟但重写的 屏蔽/遮蔽其
。因此,什么时候使用 CRTP 才是正确的,而是最简单的非平凡示例,它显示了 CRTP 相对于阴影/掩蔽的优势。do_stuff()
派生::do_stuff
I am trying to get a better understanding of CRTP. So far my understanding is that it allows one to write a functions like the following.
template <class T>
void foo(Base<T> x ) { x.do_stuff() }
Now, depending on the actual compile time derived object x
that is passed to the function foo()
, it will do different things.
However, I could have derived the class Derived
from Base
and masked/shadowed its do_stuff()
with a non-virtual but overridden Derived::do_stuff
. So when exactly is it correct to use CRTP, rather the simplest non-trivial example which shows the advantage of CRTP over shadowing/masking.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
CRTP 的要点是能够在没有虚拟性的情况下获取派生对象的类型。如果您这样做
,那么当您传递
D
对象时,bar
会调用B::foo
而不是D::foo
,因为 foo 不是虚函数。如果您希望调用D::foo
,那么您需要虚拟函数或 CRTP。使用最简单的 CRTP:
当您将
D
对象传递给bar
时,它会调用D::foo()
。另一种 CRTP 技巧会强制
D
提供foo
的实现,但您仍然需要
B
的模板参数(以便foo
正确调度),因此是模板bar
函数。另外,如果你不使用 CRTP,你最好有一个虚拟析构函数,这可能会为完全内联的轻量级类增加不必要的开销。使用 CRTP,您只需编写一个受保护的析构函数(C++0x 中的私有析构函数 +
friend T
)。The point of the CRTP is to be able to get the derived object's type without virtuality. If you do
then
bar
callsB::foo
and notD::foo
when you pass aD
object, sincefoo
isn't a virtual function. If you wantD::foo
to be called, then you need either virtual functions, or CRTP.With the simplest kind of CRTP:
this calls
D::foo()
when you pass tobar
aD
object.An alternative CRTP trick, which however forces
D
to provide an implementation forfoo
, isbut you still need a template parameter for
B
(so thatfoo
dispatches correctly), and therefore a templatebar
function.Also, if you don't do CRTP, you'd better have a virtual destructor, which might add unwanted overhead for lightweight classes which are meant to be completely inlined. With CRTP you will simply write a protected destructor (private destructor +
friend T
in C++0x).