如何在 C++ 中拥有一组结构体

发布于 2024-11-04 00:12:04 字数 426 浏览 6 评论 0原文

我有一个具有唯一键的结构。我想将这些结构的实例插入到一个集合中。我知道要做到这一点<必须重载运算符,以便 set 可以进行比较才能进行插入。

以下不起作用:

#include <iostream>
#include <set>
using namespace std;
struct foo 
{
      int key;
};

bool operator<(const foo& lhs, const foo& rhs)
{
      return lhs.key < rhs.key;
}

set<foo> bar;

int main()
{
    foo *test = new foo;
    test->key = 0;
    bar.insert(test);
}

I have a struct which has a unique key. I want to insert instances of these structs into a set. I know that to do this the < operator has to be overloaded so that set can make a comparison in order to do the insertion.

The following does not work:

#include <iostream>
#include <set>
using namespace std;
struct foo 
{
      int key;
};

bool operator<(const foo& lhs, const foo& rhs)
{
      return lhs.key < rhs.key;
}

set<foo> bar;

int main()
{
    foo *test = new foo;
    test->key = 0;
    bar.insert(test);
}

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

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

发布评论

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

评论(7

物价感观 2024-11-11 00:12:04

这可能会有所帮助:

struct foo
{
  int key;
};

inline bool operator<(const foo& lhs, const foo& rhs)
{
  return lhs.key < rhs.key;
}

如果您使用命名空间,最好在同一命名空间中声明 operator<() 函数。


为了编辑后的完整性,正如其他人指出的那样,您尝试在需要 foo 的地方添加 foo*

如果您确实想处理指针,可以将 foo* 包装到智能指针类中(auto_ptrshared_ptr,...) 。

但请注意,在这两种情况下,您都会失去重载的 operator< 的好处,该操作符在 foo 上运行,而不是在 foo* 上运行。

This might help:

struct foo
{
  int key;
};

inline bool operator<(const foo& lhs, const foo& rhs)
{
  return lhs.key < rhs.key;
}

If you are using namespaces, it is a good practice to declare the operator<() function in the same namespace.


For the sake of completeness after your edit, and as other have pointed out, you are trying to add a foo* where a foo is expected.

If you really want to deal with pointers, you may wrap the foo* into a smart pointer class (auto_ptr, shared_ptr, ...).

But note that in both case, you loose the benefit of the overloaded operator< which operates on foo, not on foo*.

迷雾森÷林ヴ 2024-11-11 00:12:04
struct Blah
{
    int x;
};

bool operator<(const Blah &a, const Blah &b)
{
    return a.x < b.x;
}

...

std::set<Blah> my_set;

但是,我不喜欢重载 operator< ,除非它具有直观意义(说一个 Blah 小于”另一个 Blah 真的有意义吗??)。如果没有,我通常提供一个自定义比较器函数:

bool compareBlahs(const Blah &a, const Blah &b)
{
    return a.x < b.x;
}

...

std::set<Blah,compareBlahs> my_set;
struct Blah
{
    int x;
};

bool operator<(const Blah &a, const Blah &b)
{
    return a.x < b.x;
}

...

std::set<Blah> my_set;

However, I don't like overloading operator< unless it makes intuitive sense (does it really make sense to say that one Blah is "less than" another Blah?). If not, I usually provide a custom comparator function instead:

bool compareBlahs(const Blah &a, const Blah &b)
{
    return a.x < b.x;
}

...

std::set<Blah,compareBlahs> my_set;
多情癖 2024-11-11 00:12:04

您也可以在类中重载 operator <

struct foo 
{
  int key;
  bool operator < (const foo &other) const { return key < other.key; }
};

在您的问题中,如果您想使用 set; bar; 作为声明,那么您应该将值插入为,

bar.insert(*test);

但这不是一个好主意,因为您正在制作冗余副本。

You can overload the operator < inside the class also as,

struct foo 
{
  int key;
  bool operator < (const foo &other) const { return key < other.key; }
};

In your question, if you want to use set<foo> bar; as declaration then, you should insert value as,

bar.insert(*test);

But that won't be a good idea, as you are making redundant copy.

单身狗的梦 2024-11-11 00:12:04

看看ereOn的回答,是对的。

您代码中的真正问题是:

foo *test = new foo;
test->key = 0;
bar.insert(test);

您在集合中插入一个指针,而不是一个结构。将 insert 更改为:

 bar.insert( *test );
 //          ^

编辑:但随后您需要删除 foo,因为它将被复制到 set 中。或者只是在堆栈上创建它(将 set 与指针一起使用不是一个好主意,因为排列会很“奇怪” - set 将根据指针进行排序地址)

see ereOn's answer, it's right.

The real problem in you code is this:

foo *test = new foo;
test->key = 0;
bar.insert(test);

You insert a pointer in the set, not a struct. Change the insert to:

 bar.insert( *test );
 //          ^

EDIT: but then you'll need to delete foo, as it will be copied in the set. Or just create it on the stack (using set with pointers is not a good idea, because the arrangement will be "strange" - the set will sort according to the pointers' addresses )

情魔剑神 2024-11-11 00:12:04

最好的办法是给 foo 一个构造函数:

struct foo
{
    foo(int k) : key(k) { }
    int key;
};

然后添加,而不是......

foo *test = new foo;
test->key = 0;
bar.insert(test);   // BROKEN - need to dereference ala *test
// WARNING: need to delete foo sometime...

你可以简单地使用:

bar.insert(foo(0));

The best thing to do is to give foo a constructor:

struct foo
{
    foo(int k) : key(k) { }
    int key;
};

Then to add, rather than...

foo *test = new foo;
test->key = 0;
bar.insert(test);   // BROKEN - need to dereference ala *test
// WARNING: need to delete foo sometime...

...you can simply use:

bar.insert(foo(0));
你曾走过我的故事 2024-11-11 00:12:04

问题不在于你的设置,而在于你的设置。它位于您的 test 对象中。你在那里使用 Java 风格。在 C++ 中,我们只需编写:

set<foo> bar;

int main()
{
    foo test; // Local variable, goes out of scope at }
    test.key = 0;
    bar.insert(test); // Insert _a copy of test_ in bar.
}

The problem isn't in your set; it's in your test object. You're using Java style there. In C++, we just write:

set<foo> bar;

int main()
{
    foo test; // Local variable, goes out of scope at }
    test.key = 0;
    bar.insert(test); // Insert _a copy of test_ in bar.
}
作业与我同在 2024-11-11 00:12:04

在c++11中我们可以使用lambda表达式,我使用的方式与@Oliver给出的方式类似。

#include <set>
#include <iostream>
#include <algorithm>

struct Blah
{
    int x;
};



int main(){

    auto cmp_blah = [](Blah lhs, Blah rhs) { return lhs.x < rhs.x;};

    std::set<Blah, decltype(cmp_blah)> my_set(cmp_blah);

    Blah b1 = {2};
    Blah b2 = {2};
    Blah b3 = {3};

    my_set.insert(b1);
    my_set.insert(b2);
    my_set.insert(b3);

    for(auto const& bi : my_set){
        std::cout<< bi.x << std::endl;
    }

}

演示

In c++11 we can use a lambda expression, I used this way which is similar to what @Oliver was given.

#include <set>
#include <iostream>
#include <algorithm>

struct Blah
{
    int x;
};



int main(){

    auto cmp_blah = [](Blah lhs, Blah rhs) { return lhs.x < rhs.x;};

    std::set<Blah, decltype(cmp_blah)> my_set(cmp_blah);

    Blah b1 = {2};
    Blah b2 = {2};
    Blah b3 = {3};

    my_set.insert(b1);
    my_set.insert(b2);
    my_set.insert(b3);

    for(auto const& bi : my_set){
        std::cout<< bi.x << std::endl;
    }

}

demo

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