从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的评论.
从[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类型.
某些函数对象否定了另一个函数对象的结果.这里我们也需要参数的类型:
templateclass 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
.