使用 C++ 概念和 CRTP 打破循环依赖

Pau*_*cas 3 c++ crtp c++-concepts c++20

我希望能够做到:

\n
template<typename T>  // line 8\nclass Base;\n\ntemplate<typename T>\nconcept C = std::is_base_of_v<Base<T>,T>;\n\ntemplate<C T>         // line 17\nclass Base {\n    // ...\n};\n\n// ...\n\nclass MyClass : public Base<MyClass> {\n    // ...\n};\n
Run Code Online (Sandbox Code Playgroud)\n

也就是说,有一个模板类Base,它将派生自它的类(CRTP 作为其模板参数。我想要一个概念来约束源自的C模板T类型。BaseTBase<T>

\n

但是,这不会编译,因为:

\n
x.cpp:17:10: error: type constraint differs in template redeclaration\ntemplate<C T>\n         ^\n
Run Code Online (Sandbox Code Playgroud)\n

我必须Base在第 8 行使用\xe2\x80\x94C来向前声明typename,但我还没有声明C,你不能向前声明概念。

\n

那么我怎样才能得到我想要的东西呢?

\n

use*_*670 5

您无法得到您想要的东西,因为在实例化时public Base<MyClass>子类MyClass仍然不完整,因此在检查时您会得到未定义的行为is_base_of

作为替代方案,您可以将相应的内容static_assert放在某些Base方法的主体中,以便稍后进行检查。