实现运算符<在 C++

发布于 2024-09-05 03:08:16 字数 811 浏览 4 评论 0 原文

我有一个带有一些数字字段的类,例如:

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

我需要使用此类的对象作为 std::map 中的键。因此我实现了operator<。此处使用的 operator< 最简单的实现是什么?

编辑: 只要任何字段不相等,就可以假定<的含义以保证唯一性。

编辑2:

一个简单的实现:

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;
}

这篇文章背后的全部原因只是我发现上面的实现太冗长了。应该有更简单的东西。

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. I therefore implement operator<. What is the simplest implementation of operator< to use here?

EDIT:
The meaning of < can be assumed so as to guarantee uniqueness as long as any of the fields are unequal.

EDIT 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

眼泪淡了忧伤 2024-09-12 03:08:16

我假设你想实现字典顺序。

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);
}

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 assume you want to implement lexicographical ordering.

Prior to 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:

#include <tuple>
bool Class1::operator<(const Class1& other) const
{
    return std::tie(a, b, c) < std::tie(other.a, other.b, other.c);
}
水溶 2024-09-12 03:08:16

我认为对 map 的要求存在误解。

map 不要求您的类定义 operator<。它需要传递合适的比较谓词,该谓词默认为 std::less,它在 Key 上使用 operator<

您不应该实现 operator< 来适应 map 中的密钥。仅当您为此类定义它时才应该实现它:即如果它有意义。

您可以完美地定义一个谓词:

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

然后:

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

I think there is a misunderstanding on what map requires.

map does not require your class to have operator< defined. It requires a suitable comparison predicate to be passed, which conveniently defaults to std::less<Key> which uses operator< on the Key.

You should not implement operator< to fit your key in the 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;
翻了热茶 2024-09-12 03:08:16

这取决于订购对您是否重要。如果没有,你可以这样做:

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;
    }
}

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;
    }
}
明媚如初 2024-09-12 03:08:16

避免多重缩进的版本是

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;
}

作者的“Edit 2”版本,平均比该解决方案有更多的比较。 (最坏情况 6 到最坏情况 3)

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. (worst case 6 to worst case 3)

凝望流年 2024-09-12 03:08:16

你可以这样做:

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

但这有很多警告 - 例如没有 vtbl,我确信还有更多。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文