代码之家  ›  专栏  ›  技术社区  ›  0x26res

如何使用bind1st和bind2nd?

  •  16
  • 0x26res  · 技术社区  · 15 年前

    我想学习如何使用绑定函数。 这是一个想法: 我有一个函数,用于参数:

    void print_i(int t, std::string separator)
    {
            std::cout << t << separator;
    }
    

    我想做的是:

    std::vector<int> elements;
    // ...
    for_each(elements.begin(), elements.end(), std::bind2nd(print_i, '\n'));
    

    但它不起作用!

    以下是我得到的:

    /usr/include/c++/4.3/backward/binders.h: In instantiation of ‘std::binder2nd<void ()(int, std::string)>’:
    main.cpp:72:   instantiated from here
    /usr/include/c++/4.3/backward/binders.h:138: error: ‘void ()(int, std::string)’ is not a class, struct, or union type
    /usr/include/c++/4.3/backward/binders.h:141: error: ‘void ()(int, std::string)’ is not a class, struct, or union type
    /usr/include/c++/4.3/backward/binders.h:145: error: ‘void ()(int, std::string)’ is not a class, struct, or union type
    /usr/include/c++/4.3/backward/binders.h:149: error: ‘void ()(int, std::string)’ is not a class, struct, or union type
    /usr/include/c++/4.3/backward/binders.h:155: error: ‘void ()(int, std::string)’ is not a class, struct, or union type
    /usr/include/c++/4.3/backward/binders.h:140: error: field ‘std::binder2nd<void ()(int, std::string)>::op’ invalidly declared function type
    /usr/include/c++/4.3/backward/binders.h: In function ‘std::binder2nd<_Operation> std::bind2nd(const _Operation&, const _Tp&) [with _Operation = void ()(int, std::string), _Tp = char]’:
    main.cpp:72:   instantiated from here
    /usr/include/c++/4.3/backward/binders.h:164: error: ‘void ()(int, std::string)’ is not a class, struct, or union type
    /usr/include/c++/4.3/bits/stl_algo.h: In function ‘_Funct std::for_each(_IIter, _IIter, _Funct) [with _IIter = __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, _Funct = std::binder2nd<void ()(int, std::string)>]’:
    main.cpp:72:   instantiated from here
    /usr/include/c++/4.3/bits/stl_algo.h:3791: error: no match for call to ‘(std::binder2nd<void ()(int, std::string)>) (int&)’
    make: *** [all] Error 1
    

    我可以使用functor,但使用binding更快。

    谢谢!

    4 回复  |  直到 6 年前
        1
  •  11
  •   Rüdiger Hanke shraddha hattimare    12 年前

    关于 bind2nd 必须是 AdaptableBinaryFunction .普通二进制函数不满足此要求(适应性函数的返回类型和参数类型需要typedef,普通函数类型不提供任何typedef)。你可以用 std::bind 不管怎样,这可能是更好的选择。

        2
  •  26
  •   azat    13 年前

    您需要使用可复制/refrencable对象,其工作原理如下:

    #include <iostream>
    #include <string>
    #include <vector>
    #include <algorithm>
    #include <functional>
    
    void print_i(int t, std::string separator)
    {
       std::cout << t << separator;
    }
    
    int main()
    {
       std::vector<int> elements;
       std::string delim = "\n";
       for_each(elements.begin(), 
                elements.end(),
                std::bind2nd(std::ptr_fun(&print_i),delim));
       return 0;
    }
    

    通常,您只需执行以下操作即可获得相同的效果:

    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <iterator>
    
    int main()
    {
       std::vector<int> elements;
       std::copy(elements.begin(),
                 elements.end(),
                 std::ostream_iterator<int>(std::cout,"\n"));
       return 0;
    }
    

    另外,假设您可以访问正在使用的STL中的tr1,那么最好用std::bind修改/替换bind1st和bind2nd的任何用法。

        3
  •  3
  •   Waqqas Farooq    14 年前

    您需要执行以下步骤:
    1。创建从std::binary_函数继承的结构(或类)
    2。在步骤1中创建的结构的operator()成员函数中定义谓词函数
    三。使用bind2nd将适当的值绑定到步骤1中创建的结构

    我在一个例子中做了所有这些。您可以通过以下链接阅读文章并下载完整的代码: bind and find

        4
  •  1
  •   James Turner    6 年前

    这些函数从C++ 11中被剔除,在C++ 17中被删除。正如上面一条评论中提到的,现在更好的解决方案是使用 std::bind 以及占位符:

    void callable(int a, int b);
    auto f = std::bind1st(&callable, 42); // returns a 1-arg function
    

    变成:

    // returns a 1-arg function
    auto f = std::bind(&callable, 42, std::placeholders::_1);