从 std::binary_function (或 std::unary 函数)继承有什么好处?
从 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
从 [unary|binary]_function 继承只会为您的类中提供额外的 typedef:
对于 unary_function
对于 binary_function
您传递给 [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
For binary_function
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.
除了 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 withstruct Foo : public unary_function<...
I already know that Foo is a functor. For a programmer (unlike compilers), types and functors are quite distinct.就像 Mykola 解释的那样,他们只是添加了 typedef。 想象一下,对于您的
PersonGreater
,您想要将第一个参数修复为某个人。binder1st
需要将第一个参数存储在某处,因此它需要第一个参数的类型。binary_function
将其作为 typedef 提供:现在,返回的
binder1st
对象知道它需要存储的参数类型是 Person 类型。一些函数对象否定另一个函数对象的结果。 这里我们也需要参数的类型:
也可以使用模板化的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. Thebinder1st
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: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:
That could also use a templated
operator()
, but the Standard defines it to use theargument_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 asstd::function
.这是编译器强制执行的一种强大的文档形式。
通过继承,您就承诺将实现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.