std::bind a bound function
I'm having trouble in detecting why the heck is this not compiling. I've got some lambda function that returns a std::function based on some argument.
I've narrowed down my problem to this snippet(which doesn't use lambdas, but reproduces my error perfectly):
#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();
}
The call to w() produces one of those lovely gcc error outputs in which I can't figure out what's going wrong. This is the error echoed by 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>)>}]
Here, f should be some callable object which takes an int as argument and calls x.bar(int) using it. On the other hand, w is just a callable object which calls some_fun(f) , being f the callable object mentioned above, which has the signature expected by some_fun 's parameter.
Am I missing something? I probably don't know how to actually mix std::bind and std::function .
std::bind expressions, like their boost::bind predecessors, support a type of composition operation. Your expression for w is roughly equivalent to
auto w=std::bind(some_fun, std::bind(&foo::bar<int>, x, std::placeholders::_1) );
Nesting binds in this manner is interpreted as
x.bar<int>(y) where y is the first parameter passed into the resulting functor. some_fun . But x.bar<int>(y) returns void, not any function type. That's why this doesn't compile.
As K-ballo points out, with boost::bind , you can fix this problem with boost::protect . As Kerrek SB and ildjarn point out, one way around this issue is: don't use auto for f . You don't want f to have the type of a bind expression. If f has some other type, then std::bind won't attempt to apply the function composition rules. You might, for instance, give f the type std::function<void(int)> :
std::function<void(int)> f = std::bind(&foo::bar<int>, x, std::placeholders::_1);
auto w = std::bind(some_fun, f);
Since f doesn't literally have the type of a bind expression, std::is_bind_expression<>::value will be false on f 's type, and so the std::bind expression in the second line will just pass the value on verbatim, rather than attempting to apply the function composition rules.
some_fun wants argument of type const std::function<void(int)> & .
std::bind returns "a function object of unspecified type T" (look at provided link, section "Return value"), that you are trying to pass as some_fun argument.
It seems this causes problem, because this argument type is not expected.
Look at: http://en.cppreference.com/w/cpp/utility/functional/bind
链接地址: http://www.djcxy.com/p/29758.html上一篇: set不是boost :: PolygonSet的成员
下一篇: std ::绑定一个绑定函数
