【问题标题】:Compile errors using std::bind in gcc 4.7在 gcc 4.7 中使用 std::bind 编译错误
【发布时间】:2013-09-01 14:17:59
【问题描述】:

我在代码的不同位置使用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&lt;int(int)&gt;foo 的类型绑定了 1 个int 参数),那么为什么bar_fun 编译失败呢?我包括了bar_fun_lvalue,因为一些谷歌搜索向我展示了rvalues used to be problematic。但这并没有解决任何问题。

它类似于this bug,但它太老了,我不认为它是相关的。

gcc 的输出并不是特别有启发性:

在 bindnew.cpp:1:0 包含的文件中: /usr/include/c++/4.7/functional:在“静态_Res”的实例化中 std::_Function_handler<_res ... _functor>::_M_invoke(const std::_Any_data&, _ArgTypes ...) [with _Res = int; _函子 = std::_Bind))(int, int)>; _ArgTypes = {int}]’:/usr/include/c++/4.7/functional:2298:6:需要来自 'std::function<_res ...>::function(_Functor, typename std::enable_if::value), std::function<_res ...>::_Useless>::type) [with _Functor = std::_Bind))(int, int)>; _Res = int; _ArgTypes = {int};类型名 std::enable_if::value), std::function<_res ...>::_Useless>::type = std::function::_Useless]’ bindnew.cpp:15:52:从这里需要 /usr/include/c++/4.7/functional:1912:40:错误:调用不匹配 '(std::_Bind))(int, int)>) (int)' /usr/include/c++/4.7/functional:1140:11:注意:候选人是: /usr/include/c++/4.7/functional:1211:2: 注意:模板 _Result std::_Bind<_functor ...>::operator()(_Args&& ...) [with _Args = {_Args . ..}; _结果 = _结果; _Functor = int (*)(int, int); _Bound_args = {int, std::_Placeholder}] /usr/include/c++/4.7/functional:1211:2: 注意:
模板参数扣除/替换失败: /usr/include/c++/4.7/functional:1206:35:错误:无法转换 参数传递中的“std::_No_tuple_element”到“int” /usr/include/c++/4.7/functional:1225:2: 注意:模板 _Result std::_Bind<_functor ...>::operator()(_Args&& ...) const [with _Args = {_Args ...}; _结果 = _结果; _Functor = int (*)(int, int); _Bound_args = {int, std::_Placeholder}] /usr/include/c++/4.7/functional:1225:2: 注意:
模板参数扣除/替换失败: /usr/include/c++/4.7/functional:1219:35:错误:无法转换 参数传递中的“std::_No_tuple_element”到“int” /usr/include/c++/4.7/functional:1239:2: 注意:模板 _Result std::_Bind<_functor ...>::operator()(_Args&& ...) volatile [with _Args = {_Args ...}; _结果 = _结果; _Functor = int (*)(int, int); _Bound_args = {int, std::_Placeholder}] /usr/include/c++/4.7/functional:1239:2: 注意:
模板参数扣除/替换失败: /usr/include/c++/4.7/functional:1233:35:错误:无法转换 参数传递中的“std::_No_tuple_element”到“int” /usr/include/c++/4.7/functional:1253:2:注意:模板 _Result std::_Bind<_functor ...>::operator()(_Args&& ...) const volatile [with _Args = { _Args ...}; _结果 = _结果; _Functor = int (*)(int, int); _Bound_args = {int, std::_Placeholder}] /usr/include/c++/4.7/functional:1253:2: 注意:模板参数扣除/替换失败: /usr/include/c++/4.7/functional:1247:35:错误:无法转换 参数传递中的“std::_No_tuple_element”到“int”

【问题讨论】:

    标签: c++11


    【解决方案1】:

    占位符位置对象(例如,当您使用_2时)不是您调用的函数中参数的位置,而是创建的可调用对象中参数的占位符。而是始终以 _1 开头并增加。

    所以:

    auto bar_auto=std::bind(foo,1,_1);
    

    等等


    这意味着您可以通过简单的操作来切换 std::bind 创建的对象中的参数

    auto bar_auto=std::bind(foo,_2,_1);
    

    当您“调用”bar_auto 对象时,第一个参数将是foo 的第二个参数,调用中的第二个参数将是foo 的第一个参数。

    【讨论】:

    • 谢谢,这一切都清楚了。获得bar_auto 的编译器警告会很有帮助。我的这种愚蠢的错误是否有任何原因不会触发警告?
    • @MarcClaesen 好吧,确实如此,但有那个冗长且难以理解的错误。 :)
    • 不过,那个转储与bar_auto 无关。我想没有警告,因为std::bind 的结果函数可能有任意数量的参数,因此无法评估给定的占位符是否不合适(在我的情况下为_2)。
    【解决方案2】:

    _2 占位符表示使用返回的仿函数的第二个参数。因此的类型

    std::bind(foo,1,_2)
    

    不是std::function&lt;int(int)&gt;而是

    std::function<int(unspecified_type, int)>
    

    要获取std::function&lt;int(int)&gt;,请使用

    std::bind(foo, 1, _1)
    //                ^^
    

    【讨论】:

      猜你喜欢
      • 2016-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-27
      • 2012-04-29
      • 2018-10-04
      • 1970-01-01
      相关资源
      最近更新 更多