在gcc 4.7中使用std :: bind编译错误

时间:2013-08-29 08:37:52

标签: c++11

我在代码的各个地方使用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'

2 个答案:

答案 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)
//                ^^