此代码只在调用CRTP的方法时编译和工作:
template <typename CRTP>
struct crtp
{
// using type = typename CRTP::type; // will not compile
void print() const
{
using type = typename CRTP::type; // compiles
static_cast<const CRTP&>(*this).print();
}
};
#include <iostream>
int main()
{
struct foo : crtp<foo>
{
using type = int;
void print() const {
std::cout << "John Cena\n";
};
} f{};
const crtp<foo>& c = f;
c.print();
return 0;
}在crtp<foo>的实例化中,foo是不完整的,但是它的方法是可以使用的。
然而,CRTP的类型不能使用CRTP外部功能的不完备性。
为什么允许将不完备性的检查推迟到调用类的函数,而不是在对象的暂存时进行?
当类主体中的using CRTP::type (未注释)出现时,将得到一个编译错误:
<source>:4:33: error: no type named 'type' in 'foo'
using type = typename CRTP::type; // will not compile
~~~~~~~~~~~~~~~^~~~发布于 2022-08-31 09:38:43
注意,即使在类模板定义中编写成员函数定义,类模板实例化时也不会实例化。
foo在其基类crtp<foo>被完全定义后才能被定义,但是crtp<foo>定义中的类型别名要求知道foo的定义,这要求已经定义了crtp<foo>,需要foo,等等。
另一方面,成员函数直到它们的类被完全定义之后才会被编译,所以类型别名在那里是可以的。
(也就是说,实例化void crtp<foo>::print() const是因为它只发生在定义了foo和crtp<foo>被实例化之后。)
将类模板定义与成员函数定义分离使两个阶段更加清晰:
template <typename CRTP>
struct crtp
{
// Can't compile unless CRTP is defined at this point.
using type = typename CRTP::type;
void print() const;
};
template <typename CRTP>
void crtp<CRTP>::print() const
{
// Also can't compile unless CRTP is defined at this point, but
// this is a later point than the class definition.
using type = typename CRTP::type;
static_cast<const CRTP&>(*this).print();
}发布于 2022-08-31 09:27:04
在CRTP中,派生类是不完整的:
struct foo : crtp<foo> // foo incomplete here
{
using type = int;
void print() const {
// foo complete here
std::cout << "John Cena\n";
}
}; // foo complete herefoo也是在void crtp<foo>::print() const中完成的。
https://stackoverflow.com/questions/73553523
复制相似问题