我尝试仅使用本文中的代码:http://blog.coldflake.com/posts/C++-delegates-on-steroids/
所以代表是这样的:
class Delegate
{
typedef void (*Type)(void* callee, int);
public:
Delegate(void* callee, Type function)
: fpCallee(callee)
, fpCallbackFunction(function) {}
template <class T, void (T::*TMethod)(int)>
static Delegate from_function(T* callee)
{
Delegate d(callee, &methodCaller<T, TMethod>);
return d;
}
void operator()(int x) const
{
return (*fpCallbackFunction)(fpCallee, x);
}
private:
void* fpCallee;
Type fpCallbackFunction;
template <class T, void (T::*TMethod)(int)>
static void methodCaller(void* callee, int x)
{
T* p = static_cast<T*>(callee);
return (p->*TMethod)(x);
}
};
带有我想要使用的功能的类是这样的:
class A
{
public:
void foo(int x)
{
printf("foo called with x=%d\n", x);
}
void bar(int x) {}
};
他在这里展示了如何使用它:
int main()
{
A a;
Delegate d = Delegate::from_function<A, &A::foo>(&a);
d(42);
}
这工作得很好,但其想法是能够实际传递这个委托到一个没有任何依赖的函数中。
所以,如果我有一个新函数,它接受一个字符串并打印它......
void printString(const std::string& str) {
std::cout << str << std::endl;
}
如何修改传递到此 printString 函数的参数,以便它可以接受此委托?我创建的新委托“d”的参数类型是什么?
类似...
void printString(const std::string& str, auto d) {
std::cout << str << std::endl;
// and then I can do something with d here
}
这样我就可以将 main() 设为这样:
int main()
{
A a;
Delegate d = Delegate::from_function<A, &A::foo>(&a);
d(42);
printString("foo", d(42)); <- note I don't know if I include the (42) here
}
所以问题是,我应该在 printString 中放入什么参数,以便我可以将 d 传递给它?
您无法轻松地将包含参数的
Delegate
传递给另一个函数。
请注意,对于 c++11 lambda 或
std::bind
/std::function
,Delegate
类不是必需的:
int main()
{
A a;
printString("foo", std::bind(&A::foo, a, 42));
printString("foo", std::bind_front(&A::foo, a, 42));
printString("foo", [&]{ a.foo(42); });
}
如果您仍然想使用
Delegate
类,那么这些技术仍然适用:
int main()
{
A a;
Delegate d = Delegate::from_function<A, &A::foo>(&a);
auto delegateOp = &Delegate::operator();
printString("foo", std::bind(delegateOp, d, 42));
printString("foo", std::bind_front(delegateOp, d, 42));
printString("foo", [&]{ d(42); });
}