在 c++ 中拥有一组结构的正确方法是什么?
What is the right way to have a set of structs in c++?
我需要一组自定义结构,以便能够快速检索具有最小给定参数的实例。但是,我发现 std::set 认为某些实例相同,即使它们具有不同的值。这是我的示例程序:
#include <set>
#include <iostream>
struct S
{
int foo, bar;
S(int foo, int bar): foo(foo), bar(bar) {}
};
inline bool operator<(const S& a, const S& b)
{
return a.foo < b.foo;
}
int main()
{
std::set<S> baz;
baz.emplace(1, 2);
baz.emplace(1, 3);
std::cout << baz.size();
return 0;
}
此程序打印1
std::set 认为S(1, 2)
和S(1, 3)
是相同的。我猜这是因为在比较它们时不使用bar
。但是我需要集合来保留这两个元素,我该如何解决这个问题?
编辑:我觉得我没有正确陈述我的问题:我想保留不完全相同的实例,但std::multiset
对我不起作用,因为我不希望容器中存在相同的实例
解决方案:我想我明白出了什么问题。我假设如果对于 2 个元素a < b
和b < a
都是真的,则会导致未定义的行为。但是 std::set 会检查这一点,因此它会删除其中一个元素。对我来说,最好的解决方案是修改比较器,使其包括bar
。
发生这种情况是因为您只比较foo
,如果foo
是等效的,则对象被视为等效的。std::set
仅保留一个等效值。如果bar
使对象唯一,请在比较中包含bar
,否则,如果您仍希望保留两个(等效)值,请使用std::multiset
。两者都是有效的解决方案,具体取决于您要执行的操作。
如果S
具有相同的foo
,则认为的实例不是std::set
,而是您自己的operator<
。
因此,您必须:
- 更改
operator<
(这也会影响排序),或 - 为您的集合使用不同的比较器(第二个类型参数),或
- 更改
operator<
以适合std::set
,并为std::sort
使用不同的Compare
参数(或者获得最小的元素)。
底线,如果你想为std::sort
(或其他)和std::set
提供不同的比较功能,你需要提供不同的功能。
由于您没有真正指定为什么您的operator<
看起来像这样(不考虑S::bar
),因此很难说什么符合您的意图。
简化一点,std::set
插入时两次比较两个元素:
a < b
b < a
如果 1. 是true
,则a
在排序中先于b
。
否则如果 2.是true
,那么b
先于a
。
否则(两者都是false
),a
和b
是等价的。
由于S{1, 2} < S{1, 3} == false
和S{1, 3} < S{1, 2} == false
根据您对operator <
的定义,它们被认为是等价的,std::set::emplace
失败。
如果foo
和bar
都使S
唯一,则可以修改operator<
以使用这两个变量,如下所示:
inline bool operator<(const S& a, const S& b)
{
if ( a.foo == b.foo )
return a.bar < b.bar;
return a.foo < b.foo;
}
也许作为其他答案的补充:
std::set
保留一个排序集,并使用operator<
创建的<
关系对元素进行排序。
所以给定两个对象a
和b
...如果! (a < b)
和! (b < a)
,那么a
既不比b
"少",也不b
"小于"a
。因此a == b
- 然而,从排序顺序的角度来看。
你可以尝试使用std::multiset
http://www.cplusplus.com/reference/set/multiset/
- 通过方法访问结构
- 有什么方法可以遍历结构吗
- 没有为自己的结构调用列表推回方法
- 在 c++ 中拥有一组结构的正确方法是什么?
- 如何在方法中传递结构参数
- 对结构方法的未定义引用
- 不同的类或结构初始化方法之间的性能差异是什么?
- 让编译器告诉什么确切的纯虚拟方法使结构抽象?
- 我想直接在结构中插入,但没有一种方法可以正确避免填充问题
- 在C++中更改结构内部元素的方法?
- 学习数据结构和算法的简单方法
- 类方法 - 数据结构中 For 循环的运行时错误
- 如何从 node-ffi 调用 c++ 中以结构向量作为参数的方法?
- 哪一个是最好的方法类或结构?在 C++ 中
- 将一种数据类型的向量复制到同一数据类型的结构向量中的有效方法是什么
- 结构/方法不起作用
- 根据输入类型选择正确的结构方法
- C++结构方法语法
- 不同参数计数的结构方法列表
- 一个c++语法问题(一种结构方法)