我尝试使用“奇异递归模板模式”来实现静态多态性,但注意到static_cast<>
通常在编译时检查一个类型是否能够转换成另一个类型,却未能检查基类声明中的打字错误,从而允许将基类向下转型为其任意子类:
#include <iostream>
using namespace std;
template< typename T >
struct CRTP
{
void do_it( )
{
static_cast< T& >( *this ).execute( );
}
};
struct A : CRTP< A >
{
void execute( )
{
cout << "A" << endl;
}
};
struct B : CRTP< B >
{
void execute( )
{
cout << "B" << endl;
}
};
struct C : CRTP< A > // it should be CRTP< C >, but typo mistake
{
void execute( )
{
cout << "C" << endl;
}
};
int main( )
{
A a;
a.do_it( );
B b;
b.do_it( );
C c;
c.do_it( );
return 0;
}
程序的输出结果为:
A
B
A
为什么这个程序可以无错误运行?我该如何在编译时检查并避免这种类型的错误?
static_cast
转换到派生类。但你无法在编译时检查运行时类型。 - molbdnilostatic_assert(std::is_base_of<CRTP<decltype(this)>,decltype(this)>::value)
? - Mooing Duckcrtp<CRTP> C { ... };
,而不需要手动继承。也就是说,我认为元类更适合将所需的 mixin 合并到新的元类中或一些通用的with_mixins<...> Foo { ... };
中。 - chrisA
和C
都是从CRTP<A>
派生而来,因此可以从CRTP<A>
进行static_cast
转换到它们中的任何一个。但是,对于不相关(或模棱两可)的类型,例如B
,则需要进行诊断。 - Arne Vogel