[英]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. 我有一些lambda函数,它基于某些参数返回
std::function
。
I've narrowed down my problem to this snippet(which doesn't use lambdas, but reproduces my error perfectly): 我将问题缩小到此代码段(不使用lambda,但完美地再现了我的错误):
#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. 调用
w()
会产生一些可爱的gcc错误输出,其中我无法弄清楚出了什么问题。 This is the error echoed by gcc 4.6.1: 这是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. 在这里,
f
应该是一些可调用的对象,它以int作为参数并使用x.bar(int)
进行调用。 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. 另一方面,
w
只是一个可调用对象,它调用上文提到的可调用对象f
的some_fun(f)
,它具有some_fun
参数所期望的签名。
Am I missing something? 我想念什么吗? I probably don't know how to actually mix
std::bind
and std::function
. 我可能不知道如何实际混合
std::bind
和std::function
。
std::bind
expressions, like their boost::bind
predecessors, support a type of composition operation. std::bind
表达式, boost::bind
前任一样,支持一种合成操作。 Your expression for w
is roughly equivalent to 您对
w
表达式大致等于
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. x.bar<int>(y)
的值,其中y
是传递到结果函子的第一个参数。 some_fun
. some_fun
。 But x.bar<int>(y)
returns void, not any function type. 但是
x.bar<int>(y)
返回void,而不是任何函数类型。 That's why this doesn't compile. 这就是为什么它不能编译的原因。
As K-ballo points out, with boost::bind
, you can fix this problem with boost::protect
. 正如K-ballo指出的那样,使用
boost::bind
可以使用boost::protect
解决此问题。 As Kerrek SB and ildjarn point out, one way around this issue is: don't use auto
for f
. 正如Kerrek SB和ildjarn所指出的,解决此问题的一种方法是:不要将
auto
用于f
。 You don't want f
to have the type of a bind expression. 您不希望
f
具有绑定表达式的类型。 If f
has some other type, then std::bind
won't attempt to apply the function composition rules. 如果
f
具有其他类型,则std::bind
将不会尝试应用函数组合规则。 You might, for instance, give f
the type std::function<void(int)>
: 例如,您可以给
f
类型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. 由于
f
实际上没有绑定表达式的类型,因此std::is_bind_expression<>::value
在f
的类型上为false,因此第二行的std::bind
表达式仅将值传递给逐字记录,而不是尝试应用功能组合规则。
some_fun
wants argument of type const std::function<void(int)> &
. some_fun
想要使用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. std :: bind返回您试图作为some_fun参数传递的“未指定类型T的函数对象”(请参见提供的链接,“返回值”部分)。
It seems this causes problem, because this argument type is not expected. 看来这会引起问题,因为不需要此参数类型。
Look at: http://en.cppreference.com/w/cpp/utility/functional/bind 查看: http : //en.cppreference.com/w/cpp/utility/functional/bind
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.