如何在VC++ 2010中使用boost::bind/std::bind与lambda函数?

18

我有一些Lambda函数,想要使用boost::bind或std::bind进行绑定。(只要能工作,不在意哪一个)。不幸的是,这两个都给我不同的编译器错误:

auto f = [](){ cout<<"f()"<<endl; };
auto f2 = [](int x){ cout<<"f2() x="<<x<<endl; };

std::bind(f)(); //ok
std::bind(f2, 13)(); //error C2903: 'result' : symbol is neither a class template nor a function template

boost::bind(f)(); //error C2039: 'result_type' : is not a member of '`anonymous-namespace'::<lambda0>'
boost::bind(f2, 13)(); //error C2039: 'result_type' : is not a member of '`anonymous-namespace'::<lambda1>'

那么,这个问题最简单的解决方法是什么?


为什么你想要使用 bind?难道你不能直接调用 f() 或 f2(1) 吗? - Jagannath
3
@Jagannath:这显然只是一个简单的例子,但实际上我想将绑定结果存储到函数对象中。 - Timo
为什么你想要使用 bind?我以为 C++0x 已经提供了闭包? - Alexandre C.
3个回答

25

你需要手动指定返回类型:

boost::bind<void>(f)();
boost::bind<int>(f2, 13)();

您还可以编写一个模板函数,使用Boost.FunctionTypes检查lambda的operator(),自动推断返回类型,如果您不想显式地告诉bind。


9
std::function<void ()> f1 = [](){ std::cout<<"f1()"<<std::endl; };
std::function<void (int)> f2 = [](int x){ std::cout<<"f2() x="<<x<<std::endl; };
boost::function<void ()> f3 = [](){ std::cout<<"f3()"<<std::endl; };
boost::function<void (int)> f4 = [](int x){ std::cout<<"f4() x="<<x<<std::endl; };

//do you still wanna bind?
std::bind(f1)(); //ok
std::bind(f2, 13)(); //ok
std::bind(f3)(); //ok
std::bind(f4, 13)(); //ok

//do you still wanna bind?
boost::bind(f1)(); //ok
boost::bind(f2, 13)(); //ok
boost::bind(f3)(); //ok
boost::bind(f4, 13)(); //ok

еҸӘжңүеҪ“functionеј•е…ҘдәҶиҝҗиЎҢж—¶й—ҙжҺҘе’Ңbindжӣҙеҝ«ж—¶пјҢе®ғжүҚжҳҜиҝҷж ·еҗ—пјҹ - Dario
我怀疑调用从bind返回的函数对象可能永远不会更快,因为在大多数情况下,bind结果会增加另一层间接性。在某些参数需要绑定的情况下,可能需要使用bind。在上面的示例中,std :: bind(f2,13)()将第一个参数绑定到常量值13。绑定的结果是一个“函数对象”,它不带参数并返回void。 - ds27680
调用 bind 的结果可能会稍微快一些,因为它不像 function 那样需要通过虚函数进行调用。 - ltjax
@ltjax 如果你尝试并调试它,你会发现两种情况下都会发生相同的事情。不同之处在于,使用bind时,直到实际调用lambda函数的调用堆栈深度更大。 - ds27680
@ltjax 我之前的评论是关于 std::bind 的。使用 boost::bind 和 boost::function 时,当调用绑定的函数对象或 boost::function 时,确实会发生不同的情况,你可能是对的,调用绑定结果可能会更快。 - ds27680
@ltjax虽然在我的测试中,直接调用boost::function比调用bind结果略微快一些(超过10000次调用)。 - ds27680

1

我认为你可能会对这篇MSDN论坛帖子感兴趣。 听起来像是发帖人遇到了和你一样的问题,并在MS Connect上提交了一个错误报告。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接