Jef*_*ler 24 c++ boost boost-bind boost-function
使用boost-bind,生成的boost函数可能会收到比绑定对象所期望的更多的参数.概念:
int func() { return 42; }
boost::function<int (int,int,int)> boundFunc = boost::bind(&func);
int answer = boundFunc(1,2,3);
Run Code Online (Sandbox Code Playgroud)
在这种情况下,func()即使其签名表明它不带参数,也会在堆栈上接收1,2和3.
这不同于更典型的使用boost::bind用于局部应用,其中的值是固定的,产生了一定的对象boost::function即需要更少的参数,但是提供正确的参数数调用绑定对象时.
以下代码适用于MSVC++ 2010 SP1.这是一种简化形式的帖子; 原始代码也适用于Linux上的g ++ 4.4.
以下是根据C++标准明确定义的吗?
#include <iostream>
#include <boost/bind.hpp>
#include <boost/function.hpp>
using namespace std;
void func1(int x) { std::cout << "func1(" << x << ")\n"; } // end func1()
void func0() { std::cout << "func0()\n"; } // end func0()
int main(int argc,char* argv[])
{
typedef boost::function<void (int)> OneArgFunc;
OneArgFunc oneArg = boost::bind(&func1,_1);
// here we bind a function that accepts no arguments
OneArgFunc zeroArg = boost::bind(&func0);
oneArg(42);
// here we invoke a function that takes no arguments
// with an argument.
zeroArg(42);
return 0;
} // end main()
Run Code Online (Sandbox Code Playgroud)
我理解为什么zeroArg(42)有效:未使用的参数由调用例程放在堆栈中,而不是被调用的例程访问.当被调用的例程返回时,调用例程清理堆栈.由于它将参数放在堆栈上,因此它知道如何删除它们.
转移到另一个架构或c ++编译器会打破这个吗?更积极的优化会打破这个吗?
我正在寻找一个更强有力的声明,无论是来自Boost文档还是来自Standards文档.我无法在两者中找到明确的立场.
使用调试器并查看程序集和堆栈,很明显,func从第一个示例中不会收到值1,2和3:在这方面你是正确的.func0在第二个例子中也是如此.至少对于我正在研究的实现,MSVC++ 2010SP1和g ++ 4.4/Linux,这是真的.
看一下引用的Boost文档,它并不像我想的那样清晰,传递额外的参数是安全的:
bind(f, _2, _1)(x, y); // f(y, x)
bind(g, _1, 9, _1)(x); // g(x, 9, x)
bind(g, _3, _3, _3)(x, y, z); // g(z, z, z)
bind(g, _1, _1, _1)(x, y, z); // g(x, x, x)
Run Code Online (Sandbox Code Playgroud)
请注意,在最后一个示例中,生成的函数对象
bind(g, _1, _1, _1)不包含对第一个参数之外的任何参数的引用,但它仍然可以与多个参数一起使用.任何额外的参数都会被默默忽略,就像在第三个示例中忽略第一个和第二个参数一样. [强调我的.]
关于额外参数被忽略的陈述并不像我想说服我在一般情况下这是真的那样明确.查看TR1,从3.6.3节可以清楚地看出,可以使用与目标对象所期望的参数数量不同的参数来调用可返回的可调用对象.这是最好的保证吗?bind
ild*_*arn 15
是的,这是安全且可移植的 - 正如文档中明确提到的,通过boost::bind静默忽略额外参数返回的bind-expression .
即,在第一示例中,func没有不接收的值1,2和3- boundFunc接收值1,2和3,并将它们转发到包含绑定表达,这可以安全地接收并且忽略它们,然后调用func().同样,在第二个示例中,zeroArg接收值42并将其转发到包含的bind-expression,它接收并忽略该值然后调用func0().
| 归档时间: |
|
| 查看次数: |
5063 次 |
| 最近记录: |