std ::绑定一个绑定函数

我在检测为什么这是不编译的麻烦。 我有一些lambda函数返回基于一些参数的std::function

我已经缩小了我的问题到这个片段(这不使用lambdas,但完美地再现了我的错误):

 #include <functional> #include <iostream> struct foo { template<class T> void bar(T data) { std::cout << data << "\n"; } }; void some_fun(const std::function<void(int)> &f) { f(12); } int main() { foo x; auto f = std::bind(&foo::bar<int>, x, std::placeholders::_1); auto w = std::bind(some_fun, f); w(); } 

w()的调用产生了那些可爱的海湾合作委员会错误输出之一,我不知道什么是错的。 这是gcc 4.6.1所回应的错误:

 g++ -std=c++0x test.cpp -o test test.cpp: In function 'int main()': test.cpp:20:7: error: no match for call to '(std::_Bind<void (*(std::_Bind<std::_Mem_fn<void (foo::*)(int)>(foo, std::_Placeholder<1>)>))(const std::function<void(int)>&)>) ()' /usr/include/c++/4.6/functional:1130:11: note: candidates are: /usr/include/c++/4.6/functional:1201:2: note: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) [with _Args = {_Args ...}, _Result = _Result, _Functor = void (*)(const std::function<void(int)>&), _Bound_args = {std::_Bind<std::_Mem_fn<void (foo::*)(int)>(foo, std::_Placeholder<1>)>}] /usr/include/c++/4.6/functional:1215:2: note: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) const [with _Args = {_Args ...}, _Result = _Result, _Functor = void (*)(const std::function<void(int)>&), _Bound_args = {std::_Bind<std::_Mem_fn<void (foo::*)(int)>(foo, std::_Placeholder<1>)>}] /usr/include/c++/4.6/functional:1229:2: note: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) volatile [with _Args = {_Args ...}, _Result = _Result, _Functor = void (*)(const std::function<void(int)>&), _Bound_args = {std::_Bind<std::_Mem_fn<void (foo::*)(int)>(foo, std::_Placeholder<1>)>}] /usr/include/c++/4.6/functional:1243:2: note: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) const volatile [with _Args = {_Args ...}, _Result = _Result, _Functor = void (*)(const std::function<void(int)>&), _Bound_args = {std::_Bind<std::_Mem_fn<void (foo::*)(int)>(foo, std::_Placeholder<1>)>}] 

在这里, f应该是一些可调用的对象,它接受一个int作为参数,并使用它调用x.bar(int) 。 另一方面, w只是一个调用some_fun(f)的可调用对象,是上述可调用对象,具有some_fun参数期望的签名。

我错过了什么吗? 我可能不知道如何实际混合std::bindstd::function

std::bindexpression式,就像它们的boost::bind前辈一样,支持一种合成操作。 你对wexpression大致相当于

 auto w=std::bind(some_fun, std::bind(&foo::bar<int>, x, std::placeholders::_1) ); 

嵌套绑定以这种方式解释为

  1. 计算x.bar<int>(y)的值,其中y是传入所得函子的第一个参数。
  2. 将该结果传递给some_fun

但是x.bar<int>(y)返回void,不是任何函数types。 这就是为什么这不编译。

正如K-ballo指出的,用boost::bind ,你可以用boost::protect来解决这个问题。 正如Kerrek SB和ildjarn所指出的,解决这个问题的一个方法是:不要对f使用auto 。 你不希望f有一个绑定expression式的types。 如果f有其他types,则std::bind将不会尝试应用函数组合规则。 例如,你可以给ftypesstd::function<void(int)>

 std::function<void(int)> f = std::bind(&foo::bar<int>, x, std::placeholders::_1); auto w = std::bind(some_fun, f); 

由于f并不具有绑定expression式的types,因此std::is_bind_expression<>::value将在f的types上为false,所以第二行中的std::bindexpression式将传递值逐字,而不是试图应用function组成规则。

some_fun需要types为const std::function<void(int)> &参数const std::function<void(int)> &

std :: bind返回“未指定typesT的函数对象”(查看提供的链接,“返回值”部分),您尝试以some_funparameter passing。

看起来这会导致问题,因为这个参数types不是预期的。

看看: http : //en.cppreference.com/w/cpp/utility/functional/bind