C++ 如何使用 bind1st 和 bind2nd?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1418756/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 19:53:50  来源:igfitidea点击:

How to use bind1st and bind2nd?

c++stlbinding

提问by Arthur

I would like to learn how to use binding functions. Here is the idea: I have this function which takes to parameters:

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

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

And I would like to do:

我想做:

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

But it does not work !

但它不起作用!

Here is what I get:

这是我得到的:

/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

I could use functor, but it is quicker to use binding.

我可以使用函子,但使用绑定会更快。

Thanks!

谢谢!

采纳答案by Rüdiger Hanke

The argument to bind2ndmust be an AdaptableBinaryFunction. A plain binary function does not fulfill this requirement (an adaptable function required typedefs for its return and argument types, a plain function type does not provide any typedefs). You could use std::bindwhich is probably the better choice anyway.

的参数bind2nd必须是一个AdaptableBinaryFunction。一个普通的二元函数不满足这个要求(一个可适应的函数需要 typedefs 作为它的返回和参数类型,一个普通的函数类型不提供任何 typedefs)。std::bind无论如何,您可以使用这可能是更好的选择。

回答by

You need to use a Copyable/Refrencable object, the following works:

您需要使用 Copyable/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;
}

Normally you can get the same effect by simply doing the following:

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

#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;
}

Also assuming you have access to TR1 in the STL you're using, its always best to revise/replace any uses of bind1st and bind2nd with std::bind

还假设您可以访问正在使用的 STL 中的 TR1,最好总是使用 std::bind 修改/替换 bind1st 和 bind2nd 的任何使用

回答by Waqqas Farooq

You need to do the following steps:
1. create a struct (or class) that inherits from std::binary_function
2. define your predicate function in the operator() member function of the struct created in step 1
3. use bind2nd to bind an appropriate value to the struct created in step 1

您需要执行以下步骤:
1. 创建一个继承自 std::binary_function 的结构(或类)
2. 在步骤 1 中创建的结构的 operator() 成员函数中定义您的谓词函数
3. 使用 bind2nd 进行绑定步骤 1 中创建的结构的适当值

I have done all this in an example. You can read the article and download the complete code on the following link: bind and find

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

回答by James Turner

These functions are deprecated since C++11 and removed in C++17. As mentioned in one comment above, the better solution now is to use std::bindand the placeholders:

这些函数自 C++11 起已弃用,并在 C++17 中删除。正如上面的一条评论中提到的,现在更好的解决方案是使用std::bind和占位符:

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

becomes:

变成:

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