【发布时间】:2023-03-21 20:33:01
【问题描述】:
当我试图理解 CRTP 时,我遇到了这个 example,它对我来说有点模糊。如果我做一些更简单的事情,我可以达到同样的结果:
#pragma once
#include <iostream>
template <typename T>
class Base
{
public:
void method() {
static_cast<T*>(this)->method();
}
};
class Derived1 // : public Base<Derived1> <-- commented inherintance
{
public:
void method() {
std::cout << "Derived1 method" << std::endl;
}
};
class Derived2 // : public Base<Derived2> <-- commmented inherintance
{
public:
void method() {
std::cout << "Derived2 method" << std::endl;
}
};
#include "crtp.h"
int main()
{
Derived1 d1;
Derived2 d2;
d1.method();
d2.method();
return 0;
}
我的问题是:CRTP 的目的是什么?经过一番思考,我猜这个用途是为了允许这样的事情:
template<typename T>
void call(Base<T>& x)
{
x.method();
}
然后这样称呼它
int main()
{
Derived1 d1;
Derived2 d2;
call(d1);
call(d2)
}
我说的对吗?
【问题讨论】:
-
CRTP 在编译时需要知道父类中的派生类型时很有用;当出于某种原因虚拟继承无法满足您的需求时。它的另一个名称是静态多态性 - 您可能会找到有关该主题的更多信息,而不是 CRTP,后者更像是达到目的的一种手段。
-
你是对的。这对 CRTP 来说是一个糟糕的例子。
-
@XerenNarcy 我的错。我没有完全阅读原始问题的 cmets 部分。我想知道的是 Etherealone 说的:“不好的例子。这段代码可以在不使用 CRTP 的情况下不使用 vtables 来完成。vtables 真正提供的是使用基类(指针或引用)来调用派生方法. 你应该在这里展示它是如何使用 CRTP 完成的”。这是我想知道的
-
@Amadeus 指出,不用担心。我提出了另一个答案,希望能比以前更好地解释这种情况(很难避免冗长,因为 some 背景信息似乎是必须的)。