C++ C++;比较运算符

C++ C++;比较运算符,c++,operators,operator-overloading,C++,Operators,Operator Overloading,我经常看到人们只覆盖运算符or==。这是否意味着默认情况下,运算符>和运算符==是使用运算符运算符< 运算符——!(运算符==| |运算符首先,否。。人们倾向于定义年龄=p.age; 这->工资=p.工资; 归还*这个; } //小于集合的运算符 bool操作员工资name==other.name)&&(this->age==other.age)); } //无序_集/无序_映射的哈希运算符 大小运算符()(const Person&p)const{ 返回std::hash()(p.name);

我经常看到人们只覆盖运算符or==。这是否意味着默认情况下,运算符>和运算符==是使用运算符<实现的

我也经常看到人们写作(见)

bool操作符()(节点常数&n1,节点常数&n2)常数
{
//托多:你的情况
返回n1.a

那么操作符()在这里是什么意思?这似乎很违反直觉

它们仅重写
的原因它们仅重写
定义的最小比较或排序运算符是
=--!接线员<

接线员--!(operator=| | operator定义的最小比较或排序运算符是
运算符==
运算符>=-->运算符<

运算符——!(运算符==| |运算符首先,否。<的实现不会隐式定义==和>。人们倾向于定义<,因为标准库使用小于运算符的特定比较来进行列表排序和类似任务

操作符()被称为函数调用操作符

struct foo {
    int operator()(int a, int b) {
        return a+b;
    }
};

现在,如果我有一个名为
x
foo
实例,我可以使用
x(6,5)
,它将使用我给出的两个参数(本例中为6和5)调用函数调用操作符。函数调用运算符仅用于将结构视为函数,可以接受任意数量和类型的参数,甚至可以不接受任何参数。在您给出的示例中,当包含该函数的对象用作函数调用时,它将比较两个节点对象,如果第一个小于第二个,则返回
true
d根据首先,否。的实现并不隐式定义==和>。人们倾向于定义<,因为标准库使用小于运算符的比较来进行列表排序和类似任务

操作符()被称为函数调用操作符

struct foo {
    int operator()(int a, int b) {
        return a+b;
    }
};

现在,如果我有一个名为
x
foo
实例,我可以使用
x(6,5)
,它将使用我给出的两个参数(本例中为6和5)调用函数调用操作符。函数调用运算符仅用于将结构视为函数,可以接受任意数量和类型的参数,甚至可以不接受任何参数。在您给出的示例中,当包含该函数的对象用作函数调用时,它将比较两个节点对象,如果第一个小于第二个,则返回
true
根据<运算符.< /p> 你看到的是实现特殊目的函数而不是通用对象的人;C++是“让你做”而不是“让你显式”的例子。

这样,你看到的是“运算符< P>”的超载,你看到的是人们实现特殊目的函数而不是通用对象;这是一个C++让你做“但不让你明确地做”的例子。


因此,您会看到“运算符的重载。这是一项常见任务,您必须重载/覆盖或定义对象的自定义比较运算符,例如将它们存储在集合/无序_集合中,或将对象用作映射/无序_映射中的键。 为此,您必须定义“小于”运算符(name=p.name; 这个->年龄=p.age; 这->工资=p.工资; 归还*这个; } //小于集合的运算符 bool操作员工资<其他工资; } //映射的等算子 布尔运算符==(常数人和其他)常数{ 返回((this->name==other.name)&&(this->age==other.age)); } //无序_集/无序_映射的哈希运算符 大小运算符()(const Person&p)const{ 返回std::hash()(p.name); } }; int main() { 设置人员设置; 个人a(“a”,203000.0),b(“b”,302000.0),c(“c”,401000.0),d(“d”,25500.0),e(“e”,31700.0); 人员设置。插入(a); 断言(personset.size()==1); 人员设置。插入(b); 断言(personset.size()==2); 人员设置。插入(c); 断言(personset.size()=3); 人员设置。插入(d); 断言(personset.size()=4); 删除(b); 断言(personset.size()=3); 删除(e); 断言(personset.size()=3); 地图人物地图; 插入({a,“first”}); 插入({b,“second”}); 插入({c,“third”}); 插入({d,“第四”}); 断言(personsMap.size()=4); PersonMap[d]=“”; 断言(PersonMap[d]=“”); personsMap.erase(b); 断言(personsMap.size()=3); personsMap.erase(e); 断言(personsMap.size()=3); 无序的人; 插入(a); 断言(personSet.size()=1); 插入(b); 断言(personSet.size()=2); 插入(c); 断言(personSet.size()=3); 自动f=个人设置。查找(b); 擦除(f); 断言(personSet.size()=2); f=个人设置。查找(e); 断言(f==personSet.end()); 无序地图; personUmap[b]=2; 断言(personUmap.size()=1); 断言(personUmap[b]==2); personUmap[c]=3; personUmap[d]=4; auto mf=personUmap.find(c); 断言(mf->first==Person({“c”,401000.0})); 断言(mf->second==3); 断言(personUmap.size()=3); personUmap.erase(mf); 断言(personUmap.size()=2); personUmap.erase(e); 断言(personUmap.size()=2); }
这是一项常见任务,您必须为对象重载/覆盖或定义自定义比较运算符,例如将它们存储在集合/无序集合中或使用对象
#include <set>
#include <string>
#include <tuple>

struct my_employee
{
    std::string name;
    int salary;
    int yearsEmployed;
};

// Saying one employee is "less" than another doesn't really make sense...
// But I can still give an *ordering* on them:
struct my_employee_ordering
{
    bool operator()(const my_employee& first, const my_employee& second) const
    {
        // I'll just reuse std::tuple's comparison operator, and tie the
        // fields of each structure into a tuple to use it. This orders
        // by name, salary, then yearsEmployed.
        return std::tie(first.name, first.salary, first.yearsEmployed) <
               std::tie(second.name, second.salary, second.yearsEmployed);
    }
};

int main()
{
    // We need to tell std::set how to order employees:
    std::set<my_employee, my_employee_ordering> x; // okay
}
struct foo
{
    void operator()(int x) { std::cout << x << std::endl; }
};

foo f;
f(5); // calls foo::operator()(5)
operator != -- !operator==
operator >= -- !operator<
operator <= -- operator== || operator <
operator >  -- !(operator== || operator <)
struct foo {
    int operator()(int a, int b) {
        return a+b;
    }
};
struct EqualityPredicate {
    bool operator()(const Node& lhs, const Node& rhs) const { return lhs == rhs; }
};

EqualityPredicate& equality;
for (Node hay : haystack) {
    if(equality(hay, haystack))
        doWork(hay);
}
#include<assert.h>
#include<set>
#include<string>
#include<unordered_map>
#include<unordered_set>
#include<map>

using namespace std;

struct Person
{
    string name;
    unsigned age;
    double wage;
    Person() :name(""), age(0), wage(0.0) {}
    Person(const string& n, unsigned a, double w) :name(n), age(a), wage(w) {}

    Person & operator=(const Person& p) {
        if (this == &p)
            return *this;
        this->name = p.name;
        this->age = p.age;
        this->wage = p.wage;
        return *this;
    }
    // less than oprator for sets
    bool operator<(const Person& other) const {
        return this->wage < other.wage;
    }
    // equal oprator for maps
    bool operator==(const Person& other)const {
        return ((this->name == other.name) && (this->age == other.age));
    }
    //hash operator for unordered_sets/unordered_maps
    size_t operator()(const Person& p) const {
        return std::hash<string>()(p.name);
    }
};

int main()
{
    set<Person> personsSet;
    Person a("a", 20, 3000.0), b("b", 30, 2000.0), c("c", 40, 1000.0), d("d", 25, 500.0), e("e", 31, 700.0);
    personsSet.insert(a);
    assert(personsSet.size() == 1);
    personsSet.insert(b);
    assert(personsSet.size() == 2);
    personsSet.insert(c);
    assert(personsSet.size() == 3);
    personsSet.insert(d);
    assert(personsSet.size() == 4);
    personsSet.erase(b);
    assert(personsSet.size() == 3);
    personsSet.erase(e);
    assert(personsSet.size() == 3);

    map<Person, string> personsMap;
    personsMap.insert({ a, "first" });
    personsMap.insert({ b, "second" });
    personsMap.insert({ c, "third" });
    personsMap.insert({ d, "fourth" });
    assert(personsMap.size() == 4);
    personsMap[d] = "";
    assert(personsMap[d] == "");
    personsMap.erase(b);
    assert(personsMap.size() == 3);
    personsMap.erase(e);
    assert(personsMap.size() == 3);

    unordered_set<Person, Person> personUset;
    personUset.insert(a);
    assert(personUset.size() == 1);
    personUset.insert(b);
    assert(personUset.size() == 2);
    personUset.insert(c);
    assert(personUset.size() == 3);
    auto f = personUset.find(b);
    personUset.erase(f);
    assert(personUset.size() == 2);
    f = personUset.find(e);
    assert(f == personUset.end());

    unordered_map<Person, int, Person> personUmap;
    personUmap[b] = 2;
    assert(personUmap.size() == 1);
    assert(personUmap[b] == 2);
    personUmap[c] = 3;
    personUmap[d] = 4;
    auto mf = personUmap.find(c);
    assert(mf->first == Person({"c", 40, 1000.0}));
    assert(mf->second == 3);
    assert(personUmap.size() == 3);
    personUmap.erase(mf);
    assert(personUmap.size() == 2);
    personUmap.erase(e);
    assert(personUmap.size() == 2);
}