C CRTP数组
作者:互联网
我可以以某种方式使用奇怪的重复模板模式(CRTP)与数组?
我想要的是?我想要一些具有一些foo函数的类.并为数组中的所有对象调用它.像这样:
template<class Derived>
struct Base{
void call(){
static_cast<Derived*>(this)->call();
}
};
struct A : Base<A>{
void call(){
cout <<"A";
}
};
struct B : Base<B>{
void call(){
cout <<"B";
}
};
...
Base array[2] = {A(), B()}; // <-- here is my array
array[0].call();
array[1].call();
附:我还读到了关于AutoList模式的内容.但它似乎与我的问题无关.
解决方法:
您可以使用另一个(非模板化)基础和虚拟调用,如下所示:
struct VirtualBase {
virtual void call () = 0;
};
template <class Derived>
struct Base : VirtualBase {
virtual void call () override {
static_cast<Derived*>(this)->real_call ();
}
};
struct A : Base<A> {
void real_call () {
cout << "A";
}
};
struct B : Base<B> {
void real_call () {
cout << "B";
}
};
并像这样使用它:
VirtualBase * a [] = {new A(), new B()};
a[0]->call ();
a[1]->call ();
请注意,要具有多态性,您需要使用指针或引用(这是您的代码的问题之一,因为您试图将实例本身放入数组中.)
另外,请注意call和real_call之间的名称更改.
并且不要忘记删除实例;例如像这样:
for (auto e : a) delete e;
或者您可以使用std :: unique_ptr<> ;,但数组的初始化将更加冗长.
有关虚拟呼叫的更新,以响应评论:
如果您希望能够分派到在运行时确定的不同方法,那么您必须使用某种间接方式.您将无法让编译器在编译时烘焙调用地址(这是普通函数调用和非虚方法调用所发生的情况.)
间接的一种形式是使用虚方法;其他人正在使用函数指针,甚至是switch语句.还有其他更奇特且使用较少的呼叫间接形式(例如运行时内存中的地址修补等),但它们很少值得付出努力.
简而言之,如果您希望具有运行时调度的灵活性,则必须付出代价.
更新另一个样本:
在回答其他答案的评论时,这里的a small sample of CRTP与多态性一起使用.这只是一个例子,而不是一个好例子,但我认为没有理由不能一起使用它们.
标签:crtp,c,arrays,templates,design-patterns 来源: https://codeday.me/bug/20190830/1770932.html