gpt4 book ai didi

c++ - C++中将成员函数绑定(bind)到对象实例的函数

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:41:40 24 4
gpt4 key购买 nike

最近,我经常将成员函数绑定(bind)到对象实例。我不想结合使用 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 函数实际上在没有参数的成员函数上运行良好,所以我很确定我的问题在于我如何处理它们,但在多次尝试修复它失败后,我想我会在这里尝试建议。

最佳答案

在开始修复 Binder 之前,请注意以下几点:

  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) {
...
}

这会让您克服眼前的错误。下一个问题是您以某种方式将绑定(bind) 参数与被调用函数的类型相关联。当然,这不是它的工作原理。在您的情况下,结果参数实际上不带任何参数,即您有这样的声明:

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');
}

关于c++ - C++中将成员函数绑定(bind)到对象实例的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27347769/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com