C ++编译时调度抽象?

时间:2015-07-18 00:58:03

标签: c++

#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的确切类型,但调度函数不知道正在进行的特定函数被称为?

1 个答案:

答案 0 :(得分:0)

使用

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());