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