如何将Boost ::函数对象与所有参数绑定



我已经在boost::functionboost::bind上阅读了,但是,如果所有参数均已绑定,我似乎无法找到一种"好方法"来调用boost函数(i认为这是正确的术语)。以下是未经测试的MCVE(复制和贴上我的真实代码不是理想的)。

#include "boost/function.hpp"
#include "boost/bind.hpp"
#include <iostream>
void func(void* args)
{
  int* myInt = static_cast<int*>(args);
  if (myInt != NULL)
  {
    std::cout << "myInt = " << *myInt << std::endl;
  }
  else
  {
    std::cout << "args is NULL" << std::endl;
  }
}
int main()
{
  int myInt1 = 5;
  int myInt2 = 45;
  boost::function<void(void* args)> myFunc = boost::bind(&func, &myInt1);
  // here's my problem,, how do I call myFunc?
  myFunc();  // this does not compile due to missing arguments
  myFunc;    // this is essentially a no-op. The function doesn't execute,
             // and if I put a breakpoint here, it either goes to the next
             // line or I get a warning that no executable code exists here
  // after some experimentation, I realized I can do this and it works
  myFunc(NULL);  // this prints out "myInt = 5"
  // this also prints out "myInt = 5"
  boost::bind(&func, &myInt1)();
  // finally, this prints out "myInt = 5" as well
  myFunc(&myInt2);
  return 0;
}

所以我的问题是,致电myFunc的首选/正确方法是什么?我已经成功地使用了_1_2,ETC占位符,通过传递适当的参数来称呼函数。实际上,几乎总是有占位符?myFunc(NULL)有效,但是对我来说,如果我已经束缚了这些论点,我似乎必须弥补参数(无论如何我所传递的内容都没关系)。在我的真实代码中,我实际上想在其他函数中调用 myFunc(所以boost::bind(&func, &myInt1)();不是一个选项),并且我在类的对象中这样做,所以我希望我提供了我提供的示例,我在真实的代码中所看到的。我正在使用Visual Studio 2013,而C 11或以后无法使用。

具有"所有参数绑定"的函数对象没有参数,因此其类型为 boost::function<void()>。您需要

boost::function<void()> myFunc = boost::bind(&func, &myInt1);

myFunc变量的更好类型是 boost::function<void()>,因为有了原始 func绑定的所有参数,实际上不需要参数来调用结果包装器。

boost::function<void()> myFunc = boost::bind(&func, &myInt1);

实际上,这将允许您仅通过:

调用该功能
myFunc();

但是,编译器允许boost::function<void(void*)>类型的原因是,boost::bind调用的结果可以用比必要的更多参数调用,而额外的参数只是被忽略。这样做的一件事是使这样的情况更加一致:

void f(int, int);
// g1 acts the same as f:
boost::function<void(int, int)> g1 = boost::bind(f, _1, _2);
// g2 swaps the order of arguments when calling f:
boost::function<void(int, int)> g2 = boost::bind(f, _2, _1);
// g3 ignores its first argument and passes the second to f twice:
boost::function<void(int, int)> g3 = boost::bind(f, _2, _2);
// g4 ignores its second argument and passes the first to f twice:
boost::function<void(int, int)> g4 = boost::bind(f, _1, _1);

g4初始化中,我们可以说bind表达式只是另一个可以使用两个int参数调用的界限,因为它不使用任何大于2的位置的占位持有人。一个参数,因为_2本身从未使用过,但这并不能使上述错误。

类似地,在您的代码初始化boost::function<void(void*)>中,编译器接受完全绑定的bind表达式作为可以用一个参数有效调用的东西,因为它不使用任何具有大于1的位置的占位符也不会将占位符_1与位置完全1一起使用,void*输入以这种方式最终被忽略。

最新更新