繁体   English   中英

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

[英]What is the benefit of inheriting from std::binary_function (or std::unary function)?

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

更新

从C ++ 11开始,不推荐使用std :: binary_function和std :: unary_function,请参阅@AlexandreC的评论。

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

对于unary_function

argument_type
result_type

对于binary_function

first_argument_type
second_argument_type
result_type 

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

如果你打算将你的Functor与其他std Functors修饰符如not1,bind1st一起使用,你必须继承自[unart | binart] _function。

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

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

就像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

它是编译器强制执行的强大文档形式。

通过继承,您承诺将实现binary_function接口,编译器将为您提供帮助。 然后,客户可以相信您的类可以在需要binary_function的任何地方使用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM