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::bind
和std::function
。
std::bind
expression式,就像它们的boost::bind
前辈一样,支持一种合成操作。 你对w
expression大致相当于
auto w=std::bind(some_fun, std::bind(&foo::bar<int>, x, std::placeholders::_1) );
嵌套绑定以这种方式解释为
- 计算
x.bar<int>(y)
的值,其中y
是传入所得函子的第一个参数。 - 将该结果传递给
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
将不会尝试应用函数组合规则。 例如,你可以给f
typesstd::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::bind
expression式将传递值逐字,而不是试图应用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