其他分享
首页 > 其他分享> > C CRTP数组

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<&gt ;,但数组的初始化将更加冗长. 有关虚拟呼叫的更新,以响应评论: 如果您希望能够分派到在运行时确定的不同方法,那么您必须使用某种间接方式.您将无法让编译器在编译时烘焙调用地址(这是普通函数调用和非虚方法调用所发生的情况.) 间接的一种形式是使用虚方法;其他人正在使用函数指针,甚至是switch语句.还有其他更奇特且使用较少的呼叫间接形式(例如运行时内存中的地址修补等),但它们很少值得付出努力. 简而言之,如果您希望具有运行时调度的灵活性,则必须付出代价. 更新另一个样本:
在回答其他答案的评论时,这里的a small sample of CRTP与多态性一起使用.这只是一个例子,而不是一个好例子,但我认为没有理由不能一起使用它们.

标签:crtp,c,arrays,templates,design-patterns
来源: https://codeday.me/bug/20190830/1770932.html