我在boost::function
和boost::bind
上曾reading up,但是,如果出现以下情况,我似乎无法找出一种调用boost
函数的“好方法”所有的论点都受到约束(我认为这是正确的术语)。下面是未经测试的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
等参数占位符调用了函数。实际上可能几乎所有时间都存在占位符? myFunc(NULL)
可以工作,但是对我来说似乎很愚蠢,如果我已经绑定了参数,那么我必须从本质上弥补这些参数(无论我传递什么都没有关系)。在我的真实代码中,我实际上想在另一个函数中调用myFunc
(因此,boost::bind(&func, &myInt1)();
不是一个选项),并且我正在一个类的对象内进行操作,所以我希望我提供的示例展示的行为与我在真实代码中看到的行为相同。我正在使用Visual Studio 2013,并且无法使用c ++ 11或更高版本。
答案 0 :(得分:3)
带有“所有参数绑定”的函数对象没有参数,因此其类型为boost::function<void()>
。您需要
boost::function<void()> myFunc = boost::bind(&func, &myInt1);
答案 1 :(得分:2)
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*
输入最终被忽略了。