将带有所有参数的成员函数传递给std :: function [英] Passing member function with all arguments to std::function

查看:294
本文介绍了将带有所有参数的成员函数传递给std :: function的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在不键入std :: placeholders :: _ 1,std :: placeholders :: _ 2等的情况下从成员函数创建std :: function-我想占位所有参数,仅保存

  struct Foo {
int bar(int,float,bool){返回0;}
};
int baz(int,float,bool){返回0;}
int main(){
Foo对象;
std :: function< int(int,int,float,bool)> fun1 = baz; // OK
std :: function< int(int,int,float,bool)> fun2 = std :: bind(& Foo :: bar,object); //错误,需要占位符
}

我不想为此提供参数阶段,我只想将函数+对象存储在某个地方。例如,我想同时具有全局函数和成员函数的std :: vector。使用FastDelegate( fastdelegate :: MakeDelegate(object,& Class :: function))很容易。



<我不想使用lambda,因为它也需要我重新输入参数。我只想要旧的FastDelegate行为。

解决方案

您可以使用函数模板来推断所有成员函数参数类型,如下所示:

  template< typename对象,typename结果,typename ... Args> 
auto make_delegate(const Obj& x,Result(Obj :: * fun)(Args ...))-> // ...

然后将返回特殊的委托对象,该对象将包含您的对象(或指向的指针)然后将所有传递的参数转发给基础对象的成员函数:

  template< typename Obj,typename Result,typename .. .Args> 
struct委托
{
Obj x;
结果(Obj :: * f)(Args ...);

template< typename ... Ts>
结果运算符()(Ts& ... args)
{
return(x。* f)(forwardTs(args)...);
}
};

您将获得以下用法语法:

  function< int(int,float,bool)> fun = make_delegate(object,& Foo :: bar); 

以下是完整示例:

  #include< functional> 
#include< iostream>
#include< utility>

使用命名空间std;

结构Foo
{
int bar(int x,float y,bool z)
{
cout<< 栏:<< x<< << y<< << z<<恩德尔
返回0;
}
};

int baz(int x,float y,bool z)
{
cout<< baz:<< x<< << y<< << z<<恩德尔
返回0;
}

template< typename对象,typename结果,typename ... Args>
struct委托
{
Obj x;
结果(Obj :: * f)(Args ...);

template< typename ... Ts>
结果运算符()(Ts& ... args)
{
return(x。* f)(forwardTs(args)...);
}
};

template< typename对象,typename结果,typename ... Args>
auto make_delegate(const Obj& x,Result(Obj :: * fun)(Args ...))
->代表< Obj,结果,Args ...>
{
Delegate< Obj,Result,Args ...>结果{x,有趣};
的返回结果;
}

int main()
{
Foo对象;
function< int(int,int,float,bool)> fun [] =
{
baz,
make_delegate(object,& Foo :: bar)//< ----用法
};
for(自动& x:乐趣)
x(1,1.0,1);
}

输出为:

  baz:1 1 1 
条形图:1 1 1

在Coliru上进行实时演示


How can I create a std::function from member function without need for typing std::placeholders::_1, std::placeholders::_2, etc - I would like to "placehold" all arguments, saving only the object itself.

struct Foo{
  int bar(int,float,bool) {return 0;}
};
int baz(int,float,bool) {return 0;}
int main() {
  Foo object;
  std::function<int(int,float,bool)> fun1 = baz; // OK
  std::function<int(int,float,bool)> fun2 = std::bind(&Foo::bar, object); // WRONG, needs placeholders
}

I don't want to provide arguments at this stage, I just want to store function + object somewhere. For example I would like to have std::vector with both global functions and member functions. It was easy to do with FastDelegate (fastdelegate::MakeDelegate(object, &Class::function)).

I don't want to use lambda as it would require me to retype arguments as well. I just want old FastDelegate behaviour.

解决方案

You can use function template which will deduce all member function parameter types, like this:

template<typename Obj, typename Result, typename ...Args>
auto make_delegate(const Obj &x, Result (Obj::*fun)(Args...)) -> // ...

And will return special delegate object, which will contain your object (or pointer to it) and just forward all passed arguments to member function of underlying object:

template<typename Obj, typename Result, typename ...Args>
struct Delegate
{
    Obj x;
    Result (Obj::*f)(Args...);

    template<typename ...Ts>
    Result operator()(Ts&&... args)
    {
        return (x.*f)(forward<Ts>(args)...);
    }
};

You will get following usage syntax:

function<int(int,float,bool)> fun = make_delegate(object, &Foo::bar);

Here is full example:

#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, float y, bool z)
{
    cout << "baz: " << x << " " << y << " " << z << endl;
    return 0;
}

template<typename Obj, typename Result, 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, typename Result, typename ...Args>
auto make_delegate(const Obj &x, Result (Obj::*fun)(Args...))
    -> Delegate<Obj, Result, Args...>
{
    Delegate<Obj, Result, Args...> result{x, fun};
    return result;
}

int main()
{
    Foo object;
    function<int(int,float,bool)> fun[] =
    {
        baz,
        make_delegate(object, &Foo::bar) // <---- usage
    };
    for(auto &x : fun)
        x(1, 1.0, 1);
}

Output is:

baz: 1 1 1
bar: 1 1 1

Live Demo on Coliru

这篇关于将带有所有参数的成员函数传递给std :: function的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆