当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《从std::binary_function(或std::unary函数)继承有什么好处?》经验,为你挑选了3个好方法。

从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{
   void operator() (Person p){
     std::cout << " Person age: " << p.age 
               << " name: " << p.name << std::endl;
   }
 };

 struct PersonGreater : public std::binary_function{
   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 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的评论.



1> Mykola Golub..:

从[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.

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



2> MSalters..:

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


严格来说,Foo永远不是一个算符.它是一种类型,或者,具体而言,是一种类型*.函子本身是函子类型的实例.

3> Johannes Sch..:

就像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 unary_negate
    : public unary_function {
    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.

推荐阅读
贾志军
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有