如何从成员函数创建一个std ::函数,而不需要键入std :: placeholder :: _ 1,std :: placeholder :: _ 2等 – 我想“保留”所有参数,只保存对象本身.
- struct Foo{
- int bar(int,float,bool) {return 0;}
- };
- int baz(int,bool) {return 0;}
- int main() {
- Foo object;
- std::function<int(int,bool)> fun1 = baz; // OK
- std::function<int(int,bool)> fun2 = std::bind(&Foo::bar,object); // WRONG,needs placeholders
- }
我不想在这个阶段提供参数,我只想把功能对象存储在某个地方.例如,我想要使用具有全局函数和成员函数的std :: vector.这很容易做到FastDelegate(fastdelegate :: MakeDelegate(object,& Class :: function)).
我不想使用lambda,因为它需要我重新引用参数.我只是想要旧的FastDelegate行为.
解决方法
您可以使用函数模板,这将推导出所有成员函数参数类型,如下所示:
- template<typename Obj,typename Result,typename ...Args>
- auto make_delegate(const Obj &x,Result (Obj::*fun)(Args...)) -> // ...
并将返回特殊的委托对象,它将包含您的对象(或指向它的对象),并将所有传递的参数转发到底层对象的成员函数:
- template<typename Obj,typename ...Args>
- struct Delegate
- {
- Obj x;
- Result (Obj::*f)(Args...);
- template<typename ...Ts>
- Result operator()(Ts&&... args)
- {
- return (x.*f)(forward<Ts>(args)...);
- }
- };
您将获得以下使用语法:
- function<int(int,bool)> fun = make_delegate(object,&Foo::bar);
这里是完整的例子:
- #include <functional>
- #include <iostream>
- #include <utility>
- using namespace std;
- struct Foo
- {
- int bar(int x,float y,bool z)
- {
- cout << "bar: " << x << " " << y << " " << z << endl;
- return 0;
- }
- };
- int baz(int x,bool z)
- {
- cout << "baz: " << x << " " << y << " " << z << endl;
- return 0;
- }
- template<typename Obj,typename ...Args>
- struct Delegate
- {
- Obj x;
- Result (Obj::*f)(Args...);
- template<typename ...Ts>
- Result operator()(Ts&&... args)
- {
- return (x.*f)(forward<Ts>(args)...);
- }
- };
- template<typename Obj,Result (Obj::*fun)(Args...))
- -> Delegate<Obj,Result,Args...>
- {
- Delegate<Obj,Args...> result{x,fun};
- return result;
- }
- int main()
- {
- Foo object;
- function<int(int,bool)> fun[] =
- {
- baz,make_delegate(object,&Foo::bar) // <---- usage
- };
- for(auto &x : fun)
- x(1,1.0,1);
- }
输出为:
- baz: 1 1 1
- bar: 1 1 1