简体   繁体   English

在C ++中实现operator <

[英]Implementing operator< in C++

I have a class with a few numeric fields such as: 我有一类带有一些数字字段的类,例如:

class Class1 {
    int a;
    int b;
    int c;
public:
    // constructor and so on...
    bool operator<(const Class1& other) const;
};

I need to use objects of this class as a key in an std::map . 我需要使用此类的对象作为std::map的键。 I therefore implement operator< . 因此,我实现了operator< What is the simplest implementation of operator< to use here? 在这里使用operator<的最简单的实现是什么?

EDIT: The meaning of < can be assumed so as to guarantee uniqueness as long as any of the fields are unequal. 编辑:只要任何字段不相等,就可以假定<的含义,以确保唯一性。

EDIT 2: 编辑2:

A simplistic implementation: 一个简单的实现:

bool Class1::operator<(const Class1& other) const {
    if(a < other.a) return true;
    if(a > other.a) return false;

    if(b < other.b) return true;
    if(b > other.b) return false;

    if(c < other.c) return true;
    if(c > other.c) return false;

    return false;
}

The whole reason behind this post is just that I found the above implementation too verbose. 这篇文章背后的全部原因仅仅是我发现上述实现过于冗长。 There ought to be something simpler. 应该有一些简单的方法。

I assume you want to implement lexicographical ordering. 我假设您要实现字典顺序。

Prior to C++11: 在C ++ 11之前:

#include <boost/tuple/tuple.hpp>
#include <boost/tuple/tuple_comparison.hpp>
bool Class1::operator<(const Class1& other) const
{
    return boost::tie(a, b, c) < boost::tie(other.a, other.b, other.c);
}

Since C++11: 从C ++ 11开始:

#include <tuple>
bool Class1::operator<(const Class1& other) const
{
    return std::tie(a, b, c) < std::tie(other.a, other.b, other.c);
}

I think there is a misunderstanding on what map requires. 我认为对map要求存在误解。

map does not require your class to have operator< defined. map不需要您的类定义operator< It requires a suitable comparison predicate to be passed, which conveniently defaults to std::less<Key> which uses operator< on the Key . 它需要传递一个合适的比较谓词,该谓词方便地默认为std::less<Key> ,它在Key上使用operator<

You should not implement operator< to fit your key in the map . 您不应该实施operator<来使您的钥匙适合map You should implement it only if you to define it for this class: ie if it's meaningful. 仅当您为此类定义它时,才应该实现它:即,如果它是有意义的。

You could perfectly define a predicate: 您可以完美地定义一个谓词:

struct Compare: std::binary_function<Key,Key,bool>
{
  bool operator()(const Key& lhs, const Key& rhs) const { ... }
};

And then: 然后:

typedef std::map<Key,Value,Compare> my_map_t;

It depends on if the ordering is important to you in any way. 这取决于订购是否对您很重要。 If not, you could just do this: 如果没有,您可以这样做:

bool operator<(const Class1& other) const
{
    if(a == other.a)
    {
         if(b == other.b)
         {
             return c < other.c;
         }
         else
         {
             return b < other.b;
         }
    }
    else
    {
        return a < other.a;
    }
}

A version which avoids multiple indentation is 避免多个缩进的版本是

bool operator<(const Class1& other) const
{
    if(a != other.a)
    {
        return a < other.a;
    }

    if(b != other.b)
    {
        return b < other.b;
    }

    return c < other.c;
}

The "Edit 2" version of the author has on average more comparisons than this solution. 作者的“编辑2”版本平均比该解决方案具有更多的比较。 (worst case 6 to worst case 3) (最坏情况6至最坏情况3)

You could do: 您可以这样做:

return memcmp (this, &other, sizeof *this) < 0;

but that has quite a lot of of caveats - no vtbl for example and plenty more I'm sure. 但这有很多警告-例如,没有vtbl,我敢肯定还有更多。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM