在C ++中将成员函数绑定到对象实例的函数

查尔斯·奥夫里亚

最近,我经常将成员函数绑定到对象实例。与其使用std :: bind,std :: mem_fn和std :: ref的组合,我想将所有这些组合成一个函数来自动处理所有这些。

例如,考虑以下代码:

#include <functional>
#include <iostream>
#include <string>

// This is the function I'd like to have working:
template <class T, typename RETURN_TYPE, typename... Arguments>
std::function<RETURN_TYPE(Arguments...)> obj_bind(RETURN_TYPE (T::*in_fun)(), T & obj, Arguments... params)
{
  return std::bind( std::mem_fn(in_fun), std::ref(obj), params...);
}

int main()
{
  // Standard use of push_back member function (our test case):
  std::string test_obj = "Test 1: ";
  test_obj.push_back('A');
  std::cout << test_obj << std::endl;

  // This WORKS:
  auto test_fun = std::bind( std::mem_fn(&std::string::push_back), std::ref(test_obj), 'B');

  // But I'd like to use this instead:
  // auto test_fun = obj_bind( &std::string::push_back, test_obj, 'C');

  test_obj = "Test 2: ";
  test_fun();
  std::cout << test_obj << std::endl;
}

我的obj_bind函数实际上可以在没有参数的成员函数上正常工作,因此我可以肯定我的问题在于如何处理这些函数,但是在尝试修复它几次失败之后,我想我会在这里尝试寻求建议。

迪特玛·库尔(DietmarKühl)

在研究固定器之前,请注意以下几点:

  1. 您真的不需要使用std::mem_fn()第一个参数,std::bind()因为std::bind()已经知道如何处理成员函数指针。
  2. 定义成员函数地址的类型是不确定的。也就是说,您不能真正std::string::push_back成为仅接受一个参数的成员函数指针。
  3. 除了使用之外,std::ref(testobj)您还可以忽略juse &testobj

如果需要一个参数,则无法推断出这样的成员函数:您需要指定参数:

template <class T, typename RETURN_TYPE, typename...Args, typename... Arguments>
std::function<RETURN_TYPE(Arguments...)>
obj_bind(RETURN_TYPE (T::*in_fun)(Args...), T & obj, Arguments... params) {
    ...
}

这可以使您克服眼前的错误。下一个问题是您以某种方式将绑定参数与要调用的函数类型相关联当然,这不是它的工作方式。在您的情况下,生成的参数实际上不带任何参数,即,您将具有如下声明:

template <class T, typename RETURN_TYPE, typename... Args, typename... Arguments>
std::function<RETURN_TYPE()>
obj_bind(RETURN_TYPE (T::*in_fun)(Args...), T & obj, Arguments... params) {
    ...
}

如果您实际上在函数中使用了占位符,则返回的值std::function<RC(...)>实际上会带有一些参数。弄清楚这些论点是不平凡的。但是,当将参数类型限制为指向函数的指针或指向成员函数的指针时,应该可以返回适当的函数对象。

只是为了好玩,这是一个似乎可以处理占位符的实现(不过,尚未经过全面测试):

#include <functional>
#include <iostream>
#include <string>

using namespace std::placeholders;

struct foo
{
    void f(int i, double d, char c) {
        std::cout << "f(int=" << i << ", double=" << d << ", char=" << c << ")\n";
    }
};

template <typename...> struct type_list;

template <typename, typename, typename, typename> struct objbind_result_type;
template <typename RC, typename... RA>
struct objbind_result_type<RC, type_list<RA...>, type_list<>, type_list<> > {
    typedef std::function<RC(RA...)> type;
};

template <typename RC,
          typename... RA,
          typename A0, typename... A,
          typename B0, typename... B>
struct objbind_result_type<RC, type_list<RA...>,
                           type_list<A0, A...>,
                           type_list<B0, B...> >;

template <bool, typename, typename, typename, typename, typename>
struct objbind_result_type_helper;
template <typename A0, typename RC, typename... RA, typename... A, typename...B>
struct objbind_result_type_helper<true, A0, RC, type_list<RA...>, type_list<A...>, type_list<B...> > {
    typedef typename objbind_result_type<RC, type_list<RA..., A0>, type_list<A...>, type_list<B...> >::type type;
};

template <typename A0, typename RC, typename... RA, typename... A, typename...B>
struct objbind_result_type_helper<false, A0, RC, type_list<RA...>, type_list<A...>, type_list<B...> > {
    typedef typename objbind_result_type<RC, type_list<RA...>, type_list<A...>, type_list<B...> >::type type;
};

template <typename RC,
          typename... RA,
          typename A0, typename... A,
          typename B0, typename... B>
struct objbind_result_type<RC, type_list<RA...>,
                           type_list<A0, A...>,
                           type_list<B0, B...> > {
    typedef typename objbind_result_type_helper<bool(std::is_placeholder<B0>::value), A0,
                                                RC, type_list<RA...>,
                                                type_list<A...>,
                                                type_list<B...> >::type type;
};


// This is the function I'd like to have working:
template <class T, typename RETURN_TYPE, typename...Args, typename... Arguments>
typename objbind_result_type<RETURN_TYPE, type_list<>, type_list<Args...>, type_list<Arguments...> >::type
obj_bind(RETURN_TYPE (T::*in_fun)(Args...), T & obj, Arguments... params)
{
  return std::bind(in_fun, &obj, params...);
}

int main()
{
  foo fo;
  auto fun = obj_bind(&foo::f, fo, _1, 2.34, _2);
  fun(17, 'b');
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在C ++ 14中将成员函数绑定到对象

来自分类Dev

将成员函数指针传递给C样式函数

来自分类Dev

将多个参数绑定到C ++中的成员函数

来自分类Dev

将多个参数绑定到C ++中的成员函数

来自分类Dev

使用JNI将C ++类成员函数绑定到Java

来自分类Dev

C ++对象实例成员函数的内存表示形式

来自分类Dev

std :: bind将成员函数绑定到nullptr的实例,导致此指针看似随机

来自分类Dev

如何使用boost :: bind将成员函数绑定到ANY对象

来自分类Dev

如何将成员函数绑定到std :: function?

来自分类Dev

将成员函数绑定到局部静态变量

来自分类Dev

如何将成员函数绑定到std :: function?

来自分类Dev

静态成员函数与C语言绑定?

来自分类Dev

C ++绑定成员函数的快速方法

来自分类Dev

构造函数中的实例化对象时的C ++类成员作用域

来自分类Dev

等价于 lambda 的标准绑定用于将成员函数绑定到标准函数

来自分类Dev

c ++ 11 lambda函数对象成员

来自分类Dev

成员函数调用和C ++对象模型

来自分类Dev

C ++类成员是一个需要构造函数的对象……这需要一个函数实例化

来自分类Dev

C ++将成员函数传递给另一个类

来自分类Dev

将成员函数传递给任意精度的C ++正交库(Quadpack ++)

来自分类Dev

用于将成员函数集调用为特定变体的正确c ++变体语法是什么?

来自分类Dev

C ++如何将成员函数指针传递给另一个类?

来自分类Dev

C ++ / Boost:将成员函数作为参数传递给boost :: bind

来自分类Dev

将成员函数传递给任意精度的C ++正交库(Quadpack ++)

来自分类Dev

用于将成员函数集调用为特定变体的正确c ++变体语法是什么?

来自分类Dev

如何使用C ++将成员的名称从结构作为参数传递给函数?

来自分类Dev

C ++ 11-将成员函数传递给线程会给出:没有重载函数需要2个参数

来自分类Dev

C ++使用可变参数模板绑定成员函数

来自分类Dev

跨DLL的C ++成员函数显式模板实例化

Related 相关文章

  1. 1

    如何在C ++ 14中将成员函数绑定到对象

  2. 2

    将成员函数指针传递给C样式函数

  3. 3

    将多个参数绑定到C ++中的成员函数

  4. 4

    将多个参数绑定到C ++中的成员函数

  5. 5

    使用JNI将C ++类成员函数绑定到Java

  6. 6

    C ++对象实例成员函数的内存表示形式

  7. 7

    std :: bind将成员函数绑定到nullptr的实例,导致此指针看似随机

  8. 8

    如何使用boost :: bind将成员函数绑定到ANY对象

  9. 9

    如何将成员函数绑定到std :: function?

  10. 10

    将成员函数绑定到局部静态变量

  11. 11

    如何将成员函数绑定到std :: function?

  12. 12

    静态成员函数与C语言绑定?

  13. 13

    C ++绑定成员函数的快速方法

  14. 14

    构造函数中的实例化对象时的C ++类成员作用域

  15. 15

    等价于 lambda 的标准绑定用于将成员函数绑定到标准函数

  16. 16

    c ++ 11 lambda函数对象成员

  17. 17

    成员函数调用和C ++对象模型

  18. 18

    C ++类成员是一个需要构造函数的对象……这需要一个函数实例化

  19. 19

    C ++将成员函数传递给另一个类

  20. 20

    将成员函数传递给任意精度的C ++正交库(Quadpack ++)

  21. 21

    用于将成员函数集调用为特定变体的正确c ++变体语法是什么?

  22. 22

    C ++如何将成员函数指针传递给另一个类?

  23. 23

    C ++ / Boost:将成员函数作为参数传递给boost :: bind

  24. 24

    将成员函数传递给任意精度的C ++正交库(Quadpack ++)

  25. 25

    用于将成员函数集调用为特定变体的正确c ++变体语法是什么?

  26. 26

    如何使用C ++将成员的名称从结构作为参数传递给函数?

  27. 27

    C ++ 11-将成员函数传递给线程会给出:没有重载函数需要2个参数

  28. 28

    C ++使用可变参数模板绑定成员函数

  29. 29

    跨DLL的C ++成员函数显式模板实例化

热门标签

归档