从 std::binary_function (或 std::unary 函数)继承有什么好处?

发布于 2024-07-14 02:51:33 字数 2202 浏览 4 评论 0原文

从 std::binary_function (或 std::unary_function)继承有什么好处?

例如,我有这样的代码:

class Person
{
 public:
    Person();
    Person(int a, std::string n);
    Person(const Person& src);

    int age;
    std::string name;
 };

 Person::Person()
           : age(0)
             , name("")
               {};

 Person::Person(int a, std::string n)
 : age(a)
 , name(n)
 {};

 Person::Person(const Person& src)
 {
   age = src.age;
   name = src.name;
 };

 struct PersonPrint : public std::unary_function<Person, void>{
   void operator() (Person p){
     std::cout << " Person age: " << p.age 
               << " name: " << p.name << std::endl;
   }
 };

 struct PersonGreater : public std::binary_function<Person, Person, bool>{
   bool operator()(const Person& p1, const Person p2){
     if (p1.age > p2.age) return true;
     if (p1.name.compare(p2.name) > 0) return true;
     return false;
   }
 };

 int main(int count, char** args)
 {
   std::vector<Person> personVec;
   Person p1(10, "Person1");
   Person p2(12, "Person2");
   Person p3(12, "Person3");

   personVec.push_back(p1);
   personVec.push_back(p2);
   personVec.push_back(p3);

   std::cout << "before sort: " << std::endl;
   std::for_each(personVec.begin(), personVec.end(), PersonPrint());
   std::sort(personVec.begin(), personVec.end(), PersonGreater());
   std::cout << "after: " << std::endl;
   std::for_each(personVec.begin(), personVec.end(), PersonPrint());
 }

但我也可以在不继承形式 std::unary_function/std::binary_function 的情况下编写此代码?

 struct PersonPrint {
     void operator() (Person p) {
         std::cout << " Person age: " << p.age << " name: " << p.name << std::endl; 
     } 
 }; 

 struct PersonGreater {
     bool operator()(const Person& p1, const Person p2) {
         if (p1.age > p2.age) return true; 
         if (p1.name.compare(p2.name) > 0) return true; 
         return false; 
     } 
 };

更新

std::binary_function 和 std::unary_function 从 C++11 开始已弃用,请参阅 @AlexandreC 的评论。

What is the benefit of inheriting from std::binary_function (or std::unary_function)?

For example I have such code:

class Person
{
 public:
    Person();
    Person(int a, std::string n);
    Person(const Person& src);

    int age;
    std::string name;
 };

 Person::Person()
           : age(0)
             , name("")
               {};

 Person::Person(int a, std::string n)
 : age(a)
 , name(n)
 {};

 Person::Person(const Person& src)
 {
   age = src.age;
   name = src.name;
 };

 struct PersonPrint : public std::unary_function<Person, void>{
   void operator() (Person p){
     std::cout << " Person age: " << p.age 
               << " name: " << p.name << std::endl;
   }
 };

 struct PersonGreater : public std::binary_function<Person, Person, bool>{
   bool operator()(const Person& p1, const Person p2){
     if (p1.age > p2.age) return true;
     if (p1.name.compare(p2.name) > 0) return true;
     return false;
   }
 };

 int main(int count, char** args)
 {
   std::vector<Person> personVec;
   Person p1(10, "Person1");
   Person p2(12, "Person2");
   Person p3(12, "Person3");

   personVec.push_back(p1);
   personVec.push_back(p2);
   personVec.push_back(p3);

   std::cout << "before sort: " << std::endl;
   std::for_each(personVec.begin(), personVec.end(), PersonPrint());
   std::sort(personVec.begin(), personVec.end(), PersonGreater());
   std::cout << "after: " << std::endl;
   std::for_each(personVec.begin(), personVec.end(), PersonPrint());
 }

But I also could write this code without inheritance form std::unary_function/std::binary_function?

 struct PersonPrint {
     void operator() (Person p) {
         std::cout << " Person age: " << p.age << " name: " << p.name << std::endl; 
     } 
 }; 

 struct PersonGreater {
     bool operator()(const Person& p1, const Person p2) {
         if (p1.age > p2.age) return true; 
         if (p1.name.compare(p2.name) > 0) return true; 
         return false; 
     } 
 };

UPDATED

std::binary_function and std::unary_function are deprecated as of C++11 see comment by @AlexandreC.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

趁年轻赶紧闹 2024-07-21 02:51:33

从 [unary|binary]_function 继承只会为您的类中提供额外的 typedef:

对于 unary_function

argument_type
result_type

对于 binary_function

first_argument_type
second_argument_type
result_type 

您传递给 [unary|binary]_function 的类型是哪些。
在你的情况下没有任何好处。

如果您要将函子与其他 std 函子修饰符(例如 not1、bind1st)一起使用,则必须从 [unart|binart]_function 继承。

如果您要出于您的目的存储此模板信息,最好使用现成的解决方案。

Inheritance from [unary|binary]_function just gives you an additional typedefs in your class:

For unary_function

argument_type
result_type

For binary_function

first_argument_type
second_argument_type
result_type 

Which are those types you pass to [unary|binary]_function.
In your case there is no benefits.

If you ever going to use your Functors with other std Functors modificators like not1, bind1st you have to inherit from [unart|binart]_function.

And if you are going to store this template information for your purpose it is better to use ready solution.

放低过去 2024-07-21 02:51:33

除了 typedef(已经提到)之外,还有可读性方面。 当我看到 struct Foo {... 时,我的第一个想法是“Foo 是一种类型”。 但是对于 struct Foo : public unary_function<... 我已经知道 Foo 是一个函子。 对于程序员(与编译器不同)来说,类型和函子是截然不同的。

Besides the typedefs (already mentioned), there is also as aspect of readability. When I see struct Foo {... my first thought will be "Foo is a type". But with struct Foo : public unary_function<... I already know that Foo is a functor. For a programmer (unlike compilers), types and functors are quite distinct.

铜锣湾横着走 2024-07-21 02:51:33

就像 Mykola 解释的那样,他们只是添加了 typedef。 想象一下,对于您的 PersonGreater,您想要将第一个参数修复为某个人。 binder1st 需要将第一个参数存储在某处,因此它需要第一个参数的类型。 binary_function 将其作为 typedef 提供:

// get a function object that compares person1 against 
// another person
std::bind1st(PersonGreater(), person1)

现在,返回的 binder1st 对象知道它需要存储的参数类型是 Person 类型。

一些函数对象否定另一个函数对象的结果。 这里我们也需要参数的类型:

template <class Predicate>
class unary_negate
    : public unary_function<typename Predicate::argument_type,bool> {
    Predicate pred;
public:
    explicit unary_negate(const Predicate& pred):pred(pred) { }
    bool operator()(const typename Predicate::argument_type& x) const {
        return !pred(x);
    }
};

也可以使用模板化的operator(),但标准将其定义为使用argument_type类型作为参数。 否定器本身是从 unary_function 派生的,并且无论如何都需要提供第一个参数类型。

有时,人们尝试使用[unary,binary]_function来存储函数对象/指针。 然而,它们不能用于此目的。 boost::function完成了这项工作,并将在下一个标准中被采用为 std::function

Like Mykola explains, they are just adding typedefs. Imagine for your PersonGreater, you want to fix the first argument to some person. The binder1st would need to store the first argument somewhere, and so it needs the type of the first argument. binary_function provides that as a typedef:

// get a function object that compares person1 against 
// another person
std::bind1st(PersonGreater(), person1)

Now, the returned binder1st object knows that the type of the argument it needs to store is of type Person.

Some function objects negate the result of another function object. Here we need the type of the argument too:

template <class Predicate>
class unary_negate
    : public unary_function<typename Predicate::argument_type,bool> {
    Predicate pred;
public:
    explicit unary_negate(const Predicate& pred):pred(pred) { }
    bool operator()(const typename Predicate::argument_type& x) const {
        return !pred(x);
    }
};

That could also use a templated operator(), but the Standard defines it to use the argument_type type as parameter. The negator itself is derived from unary_function and needs to provide the first argument type anyway.

Sometimes, people try to use [unary,binary]_function to store function objects/pointers. However, they cannot be used for that. boost::function fulfills that job and will be adopted in the next Standard as std::function.

温柔少女心 2024-07-21 02:51:33

这是编译器强制执行的一种强大的文档形式。

通过继承,您就承诺将实现binary_function 接口,并且编译器将要求您遵守它。 然后,客户可以相信您的类可以在需要 binary_function 的任何地方使用。

It's a strong form of documentation enforced by the compiler.

By inheriting, you are making a promise that you will implement the binary_function interface, and the compiler will hold you to it. Then, clients can trust that your class can be used wherever a binary_function is needed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文