我在代码的各个地方使用std::bind
时遇到了很多麻烦。有时候它会起作用,有时却不起作用,所以我认为我做的事情根本就是错误的。
据我了解,std::bind
的以下基本用法应该可以正常使用:
#include <functional>
int foo(int a, int b){ return a+b; }
int main(){
using namespace std::placeholders;
// works
auto bar_auto=std::bind(foo,1,_2);
// compile error
std::function<int(int)> bar_fun=std::bind(foo,1,_2);
int quux=1;
// compile error
std::function<int(int)> bar_fun_lvalue=std::bind(foo,quux,_2);
}
bar_auto
的类型肯定是std::function<int(int)>
(foo
的类型,其中int
个参数绑定了),为什么bar_fun
无法编译?我加入了bar_fun_lvalue
,因为有些谷歌搜索向我展示了rvalues used to be problematic。但这并没有解决任何问题。
它类似this bug,但是它太旧了,我不认为它是相关的。
gcc的输出并不是特别有启发性:
在bindnew.cpp中包含的文件中:1:0: /usr/include/c++/4.7/functional:实例化'static _Res std :: _ Function_handler&lt; _Res(_ArgTypes ...),_ Functor&gt; :: _ M_invoke(const std :: _ Any_data&amp;,_ ArgTypes ...)[with _Res = int; _Functor = std :: _ Bind))(int,int)&gt ;; _ArgTypes = {int}]':/ usr /include/c++/4.7/functional:2298:6:必需来自 'std :: function&lt; _Res(_ArgTypes ...)&gt; :: function(_Functor,typename std :: enable_if&lt;(!std :: is_integral&lt; _Functor&gt; :: value), std :: function&lt; _Res(_ArgTypes ...)&gt; :: _ Useless&gt; :: type)[with _Functor = std :: _ Bind))(int,int)&gt ;; _Res = int; _ArgTypes = {int}; typename std :: enable_if&lt;(!std :: is_integral&lt; _Functor&gt; :: value),std :: function&lt; _Res(_ArgTypes ...)&gt; :: _ Useless&gt; :: type = std :: function :: _ Useless]' bindnew.cpp:15:52:从这里需要 /usr/include/c++/4.7/functional:1912:40:错误:呼叫不匹配 '(std :: _ Bind))(int,int)&gt;)(int)' /usr/include/c++/4.7/functional:1140:11:注意:候选人是: /usr/include/c++/4.7/functional:1211:2:注意:模板_Result std :: _ Bind&lt; _Functor(_Bound_args ...)&gt; :: operator()(_ Args&amp;&amp; ...)[with _Args = {_Args ...}; _Result = _结果; _Functor = int(*)(int,int); _Bound_args = {int,std :: _ Placeholder&lt; 2&gt;}] /usr/include/c++/4.7/functional:1211:2:note:
模板参数扣除/替换失败: /usr/include/c++/4.7/functional:1206:35:错误:无法转换 参数传递中'std :: _ No_tuple_element'到'int' /usr/include/c++/4.7/functional:1225:2:注意:模板_Result std :: _ Bind&lt; _Functor(_Bound_args ...)&gt; :: operator()(_ Args&amp;&amp; ...)const [with _Args = {_ Args ...}; _Result = _Result; _Functor = int(*)(int,int); _Bound_args = {int,std :: _ Placeholder&lt; 2&gt;}] /usr/include/c++/4.7/functional:1225:2:note:
模板参数扣除/替换失败: /usr/include/c++/4.7/functional:1219:35:错误:无法转换 参数传递中'std :: _ No_tuple_element'到'int' /usr/include/c++/4.7/functional:1239:2:注意:模板_Result std :: _ Bind&lt; _Functor(_Bound_args ...)&gt; :: operator()(_ Args&amp;&amp; ...)volatile [with _Args = {_ Args ...}; _Result = _Result; _Functor = int(*)(int,int); _Bound_args = {int,std :: _ Placeholder&lt; 2&gt;}] /usr/include/c++/4.7/functional:1239:2:note:
模板参数扣除/替换失败: /usr/include/c++/4.7/functional:1233:35:错误:无法转换 参数传递中'std :: _ No_tuple_element'到'int' /usr/include/c++/4.7/functional:1253:2:注意:模板_Result std :: _ Bind&lt; _Functor(_Bound_args ...)&gt; :: operator()(_ Args&amp;&amp; ...)const volatile [ _Args = {_ Args ...}; _Result = _Result; _Functor = int(*)(int,int); _Bound_args = {int,std :: _ Placeholder&lt; 2&gt;}] /usr/include/c++/4.7/functional:1253:2: 注意:模板参数扣除/替换失败: /usr/include/c++/4.7/functional:1247:35:错误:无法转换 参数传递中的'std :: _ No_tuple_element'到'int'
答案 0 :(得分:5)
占位符位置对象(例如,当您使用_2
时)不是您调用的函数中参数的位置,而是创建的可调用对象中参数的占位符。相反,始终以_1
开头并增加。
所以:
auto bar_auto=std::bind(foo,1,_1);
等
这意味着您可以通过简单地执行
来切换std::bind
创建的对象中的参数
auto bar_auto=std::bind(foo,_2,_1);
当你&#34;打电话&#34; bar_auto
对象,第一个参数将是foo
的第二个参数,而调用中的第二个参数将是foo
的第一个参数。
答案 1 :(得分:4)
_2
占位符表示使用返回的仿函数的第二个参数。因此
std::bind(foo,1,_2)
不是std::function<int(int)>
,而是
std::function<int(unspecified_type, int)>
要获取std::function<int(int)>
,请使用
std::bind(foo, 1, _1)
// ^^