gpt4 book ai didi

c++ - CRTP与 "derived"中函数的直接实现

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:39:21 25 4
gpt4 key购买 nike

我正在尝试更好地了解 CRTP。到目前为止,我的理解是它允许编写如下函数。

template <class T>
void foo(Base<T> x ) { x.do_stuff() }

现在,根据传递给函数 foo() 的实际编译时派生对象 x,它会做不同的事情。

但是,我可以从 Base 派生类 Derived 并使用非虚拟但覆盖的方法屏蔽/隐藏它的 do_stuff() Derived::do_stuff。那么什么时候使用 CRTP 才是正确的,而不是最简单的重要示例,它显示了 CRTP 相对于阴影/掩码的优势。

最佳答案

CRTP 的重点是能够在没有虚拟性的情况下获得派生对象的类型。如果你这样做

struct B { void foo() const; }
struct D : B { void foo() const; }

void bar(const B& x) { x.foo(); }

然后 bar 在传递 D 对象时调用 B::foo 而不是 D::foo ,因为 foo 不是虚函数。如果要调用 D::foo,则需要虚函数或 CRTP。

使用最简单的 CRTP:

template <typename>
struct B { void foo() const; }

struct D : B<D> { void foo() const; }

template <typename T>
void bar(const B<T>& x)
{
static_cast<const T&>(x).foo();
}

当您向 bar 传递一个 D 对象时,这会调用 D::foo()

另一种 CRTP 技巧是

template <typename T>
struct B
{
void foo() const { static_cast<const T*>(this)->foo_impl(); }
// default implementation if needed
// void foo_impl() const { ... }
};

struct D : B<D> { void foo_impl() const { ... } };

template <typename T>
void bar(const B<T>& x) { x.foo(); }

但您仍然需要 B 的模板参数(以便 foo 正确分派(dispatch)),因此需要一个模板 bar 函数。

此外,如果您不执行 CRTP,则最好有一个虚拟析构函数,这可能会为本应完全内联的轻量级类增加不必要的开销。使用 CRTP,您只需编写一个 protected 析构函数(C++0x 中的私有(private)析构函数 + friend T)。

关于c++ - CRTP与 "derived"中函数的直接实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7239771/

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