【发布时间】:2017-12-23 02:39:34
【问题描述】:
考虑以下标准 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 进行比较,但没能成功。
【问题讨论】:
-
我不知道这是否是标准定义的行为,但您可以在
static_assert里面Base::g那个&Derived::g != &Base<Derived>::g。 -
@JohannesSchaub-litb 这很聪明!你应该写一个答案。
-
@Yakk 完成,谢谢。不过,Clang 的错误消息不是最理想的。
标签: c++ crtp pure-virtual virtual-functions