从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;
}
};
已更新
从p ++ 11开始,不推荐使用std :: binary_function和std :: unary_function,请参阅@AlexandreC的评论。答案 0 :(得分:29)
[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。
如果您要为此目的存储此模板信息,最好使用现成的解决方案。
答案 1 :(得分:16)
除了typedef(已经提到)之外,还有可读性方面。当我看到struct Foo {...
时,我的第一个念头就是“Foo是一种类型”。但是struct Foo : public unary_function<...
我已经知道Foo是一个仿函数。对于程序员(与编译器不同),类型和仿函数非常不同。
答案 2 :(得分:9)
像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
中采用。
答案 3 :(得分:3)
这是编译器强制执行的强大文档形式。
通过继承,您承诺将实现binary_function接口,编译器将为您提供帮助。然后,客户可以相信,只要需要binary_function,您的类就可以使用。