如何在 C++ 中拥有一组结构
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5816658/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to have a set of structs in C++
提问by node ninja
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.
我有一个具有唯一键的结构。我想将这些结构的实例插入到一个集合中。我知道要做到这一点,< 运算符必须重载,以便 set 可以进行比较以进行插入。
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);
}
回答by ereOn
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.
如果您使用命名空间,最好operator<()
在同一命名空间中声明函数。
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.
为了您编辑后的完整性,正如其他人所指出的,您正试图foo*
在 afoo
预期的地方添加一个。
If you really want to deal with pointers, you may wrap the foo*
into a smart pointer class (auto_ptr
, shared_ptr
, ...).
如果你真的想处理指针,你可以将 包装foo*
成一个智能指针类(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*
.
但请注意,在这两种情况下,您都失去了operator<
在foo
而非 on 上运行的重载的好处foo*
。
回答by Oliver Charlesworth
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:
但是,我不喜欢重载,operator<
除非它具有直观的意义(说一个Blah
“小于”另一个真的有意义Blah
吗?)。如果没有,我通常会提供一个自定义比较器函数:
bool compareBlahs(const Blah &a, const Blah &b)
{
return a.x < b.x;
}
...
std::set<Blah,compareBlahs> my_set;
回答by iammilind
You can overload the operator <
inside the class also as,
您也可以重载operator <
类内部,
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,
在你的问题中,如果你想使用set<foo> bar;
as 声明,你应该插入 value as,
bar.insert(*test);
But that won't be a good idea, as you are making redundant copy.
但这不是一个好主意,因为您正在制作冗余副本。
回答by Tony Delroy
The best thing to do is to give foo a constructor:
最好的办法是给 foo 一个构造函数:
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));
回答by Kiril Kirov
see ereOn's answer, it's right.
看ereOn的回答,没错。
The real problem in you code is this:
您代码中的真正问题是:
foo *test = new foo;
test->key = 0;
bar.insert(test);
You insert a pointerin the set, not a struct. Change the insert
to:
您在集合中插入一个指针,而不是一个结构。更改insert
为:
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 )
编辑:但是你需要delete foo
,因为它将被复制到set
. 或者只是在堆栈上创建它(set
与指针一起使用不是一个好主意,因为排列将是“奇怪的” -set
将根据指针的地址进行排序)
回答by MSalters
The problem isn't in your set; it's in your test
object. You're using Java style there. In C++, we just write:
问题不在你的集合中;它在你的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.
}
回答by GPrathap
In c++11 we can use a lambda expression, I used this way which is similar to what @Oliver was given.
在 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;
}
}