我们需要unary_function和binary_function做什么?
我阅读了有关二元和一元函数的教程。我理解它们的结构,但我无法想象在什么情况下我需要这些功能。你能举一个使用它们的例子吗?
http://www.cplusplus.com/reference/std/function/unary_function/
http://www.cplusplus.com/reference/std/function/binary_function/
I read the tutorials about the binary and unary functions. I understood the structure of them, but I couldn't imagine in which case I need these functions. Can you give an example for usage of them.
http://www.cplusplus.com/reference/std/functional/unary_function/
http://www.cplusplus.com/reference/std/functional/binary_function/
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这些不是函数,而是类(实际上是结构,但并不重要)。当您定义自己的二进制函数以与 STL 算法一起使用时,您可以从这些类派生它们,以便自动获取所有 typedef。
例如,
现在您不需要手动提供
argument_type
、result_type
等的 typedef。这些结构,就像iterator
结构一样,就在那里为了我们的方便,为了重用算法所需的 typedef。C++11 更新:
从 C++11 开始,新的
std::bind
并不真正需要任何 typedef,因此在某种程度上,它们已经过时了。These aren't functions, these are classes (structs, actually, but doesn't matter). When you define your own binary functions to use with STL algorithms, you derive them from these classes in order to automatically get all the typedefs.
E.g.
now you don't need to manually provide the typedefs for
argument_type
,result_type
etc. These structs, just like theiterator
struct are there just for our convenience, in order to reuse the typedefs needed for algorithms.Update for C++11:
As of C++11, the new
std::bind
does not really need any typedefs, so there are, in a way, obsolete.基本上,它们提供了允许使用函数适配器从一元和二元函数对象组合高阶函数所需的所有
typedef
。例如,这允许在需要一元的情况下使用二进制仿函数,将参数之一绑定到文字值:std::bind1st 依赖于传递给它的仿函数来提供这些类型。
AFAIK 新的 std::bind 不需要它们,因此在新代码中您似乎可以使用 std::bind 并取消它们。
Basically, they provide all the
typedef
s necessary to allow composition of higher-order functions from unary and binary function objects using function adaptors. For example, this allows using a binary functor where a unary is needed, binding one of the arguments to a literal value:std::bind1st
relies on the functor passed to it to provide those types.AFAIK the new
std::bind
doesn't need them, so it seems in new code you can usestd::bind
and do away with them.在函数对象的sgi STL文档上有一个解释。总之,unary_function 和 binary_function 用于使函子具有适应性。这允许它们与函数对象适配器一起使用,例如 unary_negate。
There's an explanation on the sgi STL documentation of Function Objects. In summary, unary_function and binary_function are used to make functors adaptable. This allows them to be used with function object adaptors such as unary_negate.
这些是什么?
std::unary_function 和 std::binary_function 是用于创建自适应函数对象的基本结构。 “可适应”一词意味着它们提供了必要的类型定义,以便与标准函数适配器(如 std::not1、std::not2、 std::bind1st、std::bind2nd。
我什么时候需要使用它们?
每次需要将自定义函数对象与标准函数适配器一起使用时,您都可以使用它们。
你有例子吗?
让我们考虑一些例子(我知道,它们是人为的。从另一方面我希望它们具有相当的描述性)。
示例 1.
假设您要打印 向量 中长度不小于特定阈值的所有字符串,并将它们打印到 std::cout。
人们可能会使用下一个函数对象:
现在任务非常简单,可以通过 std::remove_copy_if 算法执行:
如果您想使用相同的函数对象来打印所有字符串怎么办其长度严格小于阈值?
我们可以想出的明显解决方案是使用 std::not1 函数适配器:
事实上,上面的代码将无法编译,因为我们的 LengthThreshold 不具有适应性,并且没有 std::not1 所必需的 typedef。
为了使其具有适应性,我们需要继承 std::unary_function:
现在我们的第一个示例就像一个魅力。
示例 2。
让我们更改一下之前的示例。假设我们不想在函数对象内存储阈值。在这种情况下,我们可以将函数对象从一元谓词更改为二元谓词:
并利用 std::bind2nd 函数适配器:
C++11 及更高版本怎么样?
上面的所有示例都特意仅使用C++ 03。
原因是 std::unary_function 和 std::binary_function 自 C++ 11 起已弃用,并从 C++ 17 中完全删除嗯>。
它是随着更通用和灵活的函数的出现而发生的,例如 std::bind 使得从 std::unary_function 和 std::binary_function 继承变得多余。
What are they?
std::unary_function and std::binary_function are base structs for creation adaptable function objects. The word adaptable means that they provide necessary typedefs for being used in conjunction with standard function adaptors like std::not1, std::not2, std::bind1st, std::bind2nd.
When I need to use them?
You may use them every time you need to use your custom function object together with standard function adaptor.
Do you have an example?
Lets consider some examples (I know, they are artificial. From the other side I hope, that they are rather descriptive).
Example 1.
Suppose you want to print all strings in a vector with their lengths not less than a particular threshold and print them to std::cout.
One might use the next function object:
Now the task is pretty simple and can be performed by std::remove_copy_if algorithm:
What if you want to use the same function object to print all the strings with their lengths strictly less than the threshold?
The obvious solution we can come up with is the usage of std::not1 function adaptor:
In fact, the code above won't compile because our LengthThreshold is not adaptable and has no typedefs which are necessary for std::not1.
To make it adaptable we need to inherit from std::unary_function:
Now our first example works like a charm.
Example 2.
Lets change our previous example. Suppose we don't want to store a threshold inside the function object. In such case we may change the function object from unary predicate to binary predicate:
And make use of std::bind2nd function adaptor:
What about C++11 and higher?
All the examples above intentionally use only C++ 03.
The reason is that std::unary_function and std::binary_function are deprecated since C++ 11 and completely removed from C++ 17.
It happened with the advent of more generalized and flexible functions like std::bind which make inheriting from std::unary_function and std::binary_function superfluous.