C++ CRTP铸造规范
从核心概念为this指针转换的基本CRTP开始-C++ CRTP铸造规范,c++,templates,crtp,C++,Templates,Crtp,从核心概念为this指针转换的基本CRTP开始- #include "stdafx.h" #include <iostream> using namespace std; template<class T> class A { public: void a0(){ static_cast<B*>(this)->a2(); } void a2(){ cout << "a2 base" << endl; } };
#include "stdafx.h"
#include <iostream>
using namespace std;
template<class T>
class A
{
public:
void a0(){ static_cast<B*>(this)->a2(); }
void a2(){ cout << "a2 base" << endl; }
};
class B: public A<int>//<int>
{
public:
void a1(){ a0(); }
void a2(){ cout << "a2 derived" << endl; }
};
int _tmain(int argc, _TCHAR* argv[])
{
B b;
b.a1();
return 0;
}
#包括“stdafx.h”
#包括
使用名称空间std;
样板
甲级
{
公众:
void a0(){static_cast(this)->a2();}
void a2(){cout
- 如果
A
不是模板,则强制转换失败,因为static\u cast
允许多种强制转换类型,并且它不知道A
和B
之间的关系,因此强制转换失败
- 在模板案例中,强制转换成功只是因为MSVC中有一个错误。由于
B
是一个非依赖类型名称,它的行为应该与非模板案例相同。但是,MSVC不正确地将检查推迟到实例化点,直到它知道a
和B
之间的关系为止。(我试着在g++上编译,结果果然失败了)
另外,请注意,您所做的根本不是CRTP。在正常的CRTP中,您可能希望强制转换为t*
notB*
,然后编译就可以了。我还假设您的意思是class B:public a
notclass B:public a
这不是模板实例化的问题,而是顺序的问题定义
声明类A时,类B仍然未知,因此,您不能要求编译器验证静态\u转换或动态\u转换。此时,只有重新解释\u转换或C样式转换才有效
但是很容易修复:在声明B之后,只需拒绝定义a0
:
class B;
class A
{
public:
void a0();
void a2(){ cout << "a2 base" << endl; }
};
class B: public A
{
public:
void a1(){ a0(); }
void a2(){ cout << "a2 derived" << endl; }
};
void A::a0() {
static_cast<B*>(this)->a2();
}
B类;
甲级
{
公众:
无效a0();
void a2(){cout Great,谢谢。代码是sic-因此关键点是传入类型以便静态_cast工作。Sry我没有代表-两个答案都很好,因此我必须任意接受一个。
class B;
class A
{
public:
void a0();
void a2(){ cout << "a2 base" << endl; }
};
class B: public A
{
public:
void a1(){ a0(); }
void a2(){ cout << "a2 derived" << endl; }
};
void A::a0() {
static_cast<B*>(this)->a2();
}