如何考虑两个结构相等而不管它们的第二个属性?

时间:2018-03-19 04:32:38

标签: c++ compare

我有这个结构

struct Event {
    const string event;
    const int order;
    Event(const string& _event, const int& _order):event(_event),order(_order) {}
};

struct EventCompare {
    bool operator()(const Event& lhs, const Event& rhs)
    {
        return (lhs.order < rhs.order);
    }
};

我想在set中使用

set<Event, EventCompare> events;

我知道套装不允许重复。但是,我想将重复项定义为structs的两个实例,其中events 等于,无论其命令是什么,换句话说,A = B iff {{1} }。此定义必须影响集合的工作方式,这意味着,例如,如果集合已包含A.event == B.event,则集合必须忽略Event("holiday", 1)

我该怎么做?我试图添加

Event("holiday", 0)

在我的if (lhs.event == rhs.event) return false; 中,但是没有用。无论如何都会使用EventCompare代替pair吗?

4 个答案:

答案 0 :(得分:2)

如果在您指定的条件下它们被认为是相等的,那么很明显var request = require('request'); var headers = { 'authorization': 'CloudSight My_Key', 'cache-control': 'no-cache', 'content-type': 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' }; var options = { url: 'https://api.cloudsight.ai/v1/images', method: 'POST', headers: headers }; function callback(error, response, body) { if (!error && response.statusCode == 200) { console.log(body); } } request(options, callback); 比较的结果将是错误的。一个不低于另一个,它们被认为是平等的。为了与关联容器一起使用,比较运算符只需要指示一个实例是否为“#34; less&#34;比另一个。因为在这种情况下,它们被认为是平等的,所以没有一个比另一个小。

因此:

 clang++-6.0 -std=c++17 -stdlib=libc++ hello.cc -o hello 
/usr/bin/ld: cannot find -lc++abi
clang: error: linker command failed with exit code 1 (use -v to see invocation)

但是,这并未解决<对象的两个实例具有相同struct EventCompare { bool operator()(const Event& lhs, const Event& rhs) { if (lhs.event == rhs.event) return false; return (lhs.order < rhs.order); } }; 但不同Event的情况。如果不能出现这种情况,您不必担心。如果可以,只需确定它们的排序,并在这种情况下相应地设置比较运算符的返回值。

答案 1 :(得分:2)

您可以使用的最接近的是:

struct EventCompare {
    bool operator()(const Event& lhs, const Event& rhs)
    {
        if (lhs.event == rhs.event)
             return false;

        return (lhs.order < rhs.order);
    }
};

但是,您要求的比较条件不符合strictly weak ordering,这是将对象放入std::set所必需的。

让您拥有三个包含以下数据的对象:

obj1 = {"foo", 200}
obj2 = {"bar", 300}
obj3 = {"foo", 400}

如果您按照obj1obj2obj3的顺序向对象添加对象,则只能按顺序看到obj1obj2 ,在集合中。

如果您按照obj2obj3obj1的顺序向对象添加对象,则只能按顺序看到obj2obj3 ,在集合中。

根据首先添加到集合中的对象,您不仅会在集合中获得不同的对象,而且甚至对象也会根据首先添加到集合中的对象以不同的顺序显示。如果你遵循这个策略我将来只能看到问题。

我认为您应该重新审视您的要求并寻找更清洁的解决方案。如果不深入了解你的目标,我无法提出解决方案。

答案 2 :(得分:0)

set并不寻求平等。它只检查订购。

因为如果event相同,你想要两个事件相等,这意味着它们都不会出现在另一个事件之前,并且在这种情况下你的比较函数应该返回false

bool operator()(const Event& lhs, const Event& rhs) const {
    return lhs.event != rhs.event && lhs.order < rhs.order;
}

然而,由于不再定义严格弱排序,因此无法正常工作,因为您可以拥有A < B和{{}的事件1}}但B < C如果!(A < C)A匹配C字符串但event的顺序介于B&#之间39; s和A&#39; s。

所以不,你不能使用一个集来存储第二个非排序属性覆盖排序元素的元素。您必须更改基于C的排序,但之后您无法根据event查找内容。

您可以使用ordermap字符串映射到用于将其存储到event的{​​{1}}值。然后检查地图以查看它是否已存在,并确定要保留在集合中的元素。否则,使用新条目更新集合和地图。

答案 3 :(得分:0)

我似乎错过了一些令人眼花缭乱的事情。但你当然需要做的就是根据你的要求进行比较吗?

struct EventCompareName
{
    bool operator()(const Event& lhs, const Event& rhs)
    {
        // If you want to compare by event and not order, then do so.
        return (lhs.event < rhs.event);
        // Rather than comparing by order and not event.
        //return (lhs.order < rhs.order);
    }
};

std::set<Event, EventCompareName> events;

当然,在某些情况下,您可能 想要通过order进行比较(即使您的问题绝对没有表明该要求)。在这种情况下:

struct EventCompareNameOrder
{
    bool operator()(const Event& lhs, const Event& rhs)
    {
        if (lhs.event != rhs.event)
            return (lhs.event < rhs.event);

        return (lhs.order < rhs.order);
    }
};

std::set<Event, EventCompareNameOrder> allEvents;