c++编译时调度抽象

C++ compile time dispatch abstraction?

本文关键字:抽象 调度 编译 c++      更新时间:2023-10-16
#include <iostream>
struct object1 {
    object1(int v) : type(1), value(v) {}
    int type;
    int value;
};
struct object2 {
    object2(int v) : type(2), value(v) {}
    int type;
    int value;
};
template <typename HeaderType>
void foo(HeaderType * hdr) {
    std::cout << "foo called with type " << hdr->type << " and value " << hdr->value << std::endl;
}
// this function doesn't work
template <typename HandlerType>
void dispatch(int type, int val, HandlerType handler) {
    if (type == 1) {
        object1 h(val);
        handler(&h);
    } else {
        object2 h(val);
        handler(&h);
    }
}
int main() {
    int type = 1;
    int val = 1;
    // this part works
    if (type == 1) {
        object1 h(val);
        foo(&h);
    } else {
        object2 h(val);
        foo(&h);
    }
    // trying to replicate the above behavior in a more abstract way,
    // ideally via a function call of the following sort
    //
    // dispatch(type, val, ..foo..? );
}

上面的程序接受一个输入值,用它来决定创建什么类型的对象,然后用指向该对象的指针调用函数foo。

问题:是否有可能创建这样的抽象,调度的调用者不知道foo将被调用的确切类型,但调度函数不知道将要被调用的具体函数?

With

template <typename HandlerType>
void dispatch(int type, int val, HandlerType handler) {
    if (type == 1) {
        object1 h1(val);
        handler(&h1);
    } else {
        object2 h2(val);
        handler(&h2);
    }
}

所有分支都应该是有效的,所以handler(&h1)handler(&h2)应该是有效的调用。

为此,handler可能是一个泛型lambda(从c++ 14开始),如注释所示:

dispatch(type, val, [](auto a) {return foo(a);} );

或者可以创建自己的函子:

struct foo_caller
{
    template <typename HeaderType>
    void operator () (const HeaderType* hdr) const {
        std::cout << "foo called with type " << hdr->type << " and value " << hdr->value << std::endl;
    }
};

然后命名为:

dispatch(type, val, foo_caller());