【问题标题】:Using std::bind to bind parameters and object instance separately使用 std::bind 分别绑定参数和对象实例
【发布时间】:2016-08-08 10:43:09
【问题描述】:

是否可以将参数绑定到成员函数调用,然后单独绑定目标对象?

我试图实现的是一个辅助函数,它接收一个带有任意参数的函数作为参数,然后在集合中的所有项目上执行它。

void SomeType::Work(UINT a, UINT b, UINT c)
{
    //do something
}

template<typename Function, class Container>
void Execute(const Function& fn, const Container& collection)
{
    for(auto& item : collection)
    {
        auto bound = std::bind(fn, &item);
        bound();
    }
}

void Test()
{
    //eg. container = vector of SomeType
    auto fn = std::bind(&Sometype::Work, 10, 20, 30);
    Execute(fn, container);
}

这在功能中出现了一些错误而失败:

error C2064: term does not evaluate to a function taking 3 arguments

最终指向:

see reference to function template instantiation 'void Execute<std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall SomeType::* )(UINT,UINT,UINT),void,SomeType,UINT,UINT,UINT>,UINT &,UINT &,UINT &>>(const Function &)' being compiled
with
[
    Function=std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall SomeType::* )(UINT,UINT,UINT),void,SomeType,UINT,UINT,UINT>,UINT &,UINT &,UINT &>
]

我只是通过传入一个 lambda 表达式来解决它,该 lambda 表达式捕获所需的值并在传递给它的对象上执行所需的函数。我仍然想知道这种方式的绑定函数是否有任何作用,我只是做错了,或者它是否不可行。

【问题讨论】:

  • Sometype::Work 的定义在哪里?
  • 它只是一个接受最初定义的参数的函数。在上面添加了一个示例定义。
  • 你绑定绑定了吗?我发现 lambda 更清晰,递归怪癖更少。

标签: c++ c++11 std stdbind


【解决方案1】:

在绑定成员函数Sometype::Work()时,您应该为将在第二次绑定时绑定的目标对象留一个占位符。

试试这个:

using namespace std::placeholders;
auto fn = std::bind(&Sometype::Work, _1, 10, 20, 30);
                                     ~~

LIVE

【讨论】:

  • ...顺便说一句:,拜托,你是如何在LIVE 超链接周围找到那个花哨的框的? - 我还不知道如何在我的答案中做到这一点
  • 有趣,这似乎很有希望。我一会儿再试一下
  • @WhiZ ...但请不要那样做。这是对格式标签的滥用。
  • 这当然有效。感谢您清除它:)
【解决方案2】:

听起来您只是想将一个函数(带有特定参数)应用于集合。

我看不出这与使用带有特定功能的 std::for_each 有何不同。

void Test()
{
    //eg. container = vector of SomeType
    auto fn1 = [/*whatever*/](const container_value_type& obj) { 
        Sometype::Work(10, 20, 30, obj);
    }
    auto fn2 = [/*whatever*/](const container_value_type& obj) { 
        Sometype::Work(40, 50, 60, obj);
    }
    std::for_each(container.begin(), container.end(), fn1);
    std::for_each(container.begin(), container.end(), fn2);
}

【讨论】:

  • 唯一的区别是界面美观。不必复制所有 for_each 和迭代器 begin.end 等。这就是我制作助手的原因,因为它被用于一堆函数(仅将所有调用转发到持有的项目的容器)中,否则我只会用于 for_each 或基于范围的 for
  • 好的,那么为什么不使用你的Execute,而不是使用 std::bind,使用 std::for_each。我的意思是您将项目绑定到函数并在调用它之后立即绑定,那么为什么不直接调用它并传递项目。恕我直言,你过度设计它......
  • 不回答问题
  • @ZivS 正如我在帖子中提到的,我确实做了不同的事情,通过使用 lambda 并将其传递给将进行迭代的函数。我只是对 std::bind 的用法感到好奇
猜你喜欢
  • 2013-01-26
  • 2015-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-14
相关资源
最近更新 更多