考虑以下标准 CRTP 示例:
#include <iostream>
template<class Derived>
struct Base {
void f() { static_cast<Derived *>(this)->f(); }
void g() { static_cast<Derived *>(this)->g(); }
};
struct Foo : public Base<Foo> {
void f() { std::cout << 42 << std::endl; }
};
int main() {
Foo foo;
foo.f(); // just OK
foo.g(); // this will stack overflow and segfault
}
如果这是常规的虚拟继承,我可以标记虚拟 f
和 g
方法一样纯粹
struct Base {
virtual void f() = 0;
virtual void g() = 0;
};
并得到一个关于 Foo
的编译时错误是抽象的。但是 CRTP 没有提供这样的保护。我可以以某种方式实现它吗?运行时检查也是可以接受的。我想过比较this->f
带有 static_cast<Derived *>(this)->f
的指针,但没能成功。
最佳答案
你可以在编译时断言两个指向成员函数的指针是不同的,例如:
template<class Derived>
struct Base {
void g() {
static_assert(&Derived::g != &Base<Derived>::g,
"Derived classes must implement g().");
static_cast<Derived *>(this)->g();
}
};
关于c++ - 保护 CRTP 模式免受 "pure virtual"调用中的堆栈溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45163209/