简体   繁体   English

std :: set中的顺序和std :: unordered_set的差异

[英]Order in std::set and difference to std::unordered_set

I expected the order of std::set to be consistent like std::list or std::vector , only that a value will not be appended a second time. 我期望std::set的顺序像std::liststd::vector一样一致,只是第二次不会附加值。 MSVC 110 prooved me wrong. MSVC 110证明我错了。 I expected the following code the yield the result shown below, which is the case when running the code on ideone ( http://ideone.com/e47GwQ ) (not sure which compiler and version they use, though). 我期望下面的代码产生如下所示的结果,这是在ideone( http://ideone.com/e47GwQ )上运行代码时的情况(尽管不确定使用的是哪个编译器和版本)。

#include <iostream>
#include <set>

template <typename C>
int insert_get_index(C& container, typename C::value_type value)
{
    typename C::iterator it = container.insert(value).first;
    return std::distance(container.begin(), it);
}

int main()
{
    int a = 3, b = 1, c = 9;
    std::set<int*> set;

    std::cout << insert_get_index(set, &a) << "\n";
    std::cout << insert_get_index(set, &b) << "\n";
    std::cout << insert_get_index(set, &c) << "\n";
    std::cout << insert_get_index(set, &a) << "\n";
    std::cout << insert_get_index(set, &b) << "\n";
    std::cout << insert_get_index(set, &c) << "\n";

    return 0;
}
0
1
2
0
1
2

Running the code in Visual Studio 2012 yields what you can see below. 在Visual Studio 2012中运行代码将产生以下内容。

0
0
2
1
0
2

Now, why did I thin that std::set behaves like described above? 现在,为什么我使std::set变薄,就像上面描述的那样? Because cplusplus.com states 因为cplusplus.com指出

Sets are containers that store unique elements following a specific order. 集合是按照特定顺序存储唯一元素的容器。

and additionally, there is std::unordered_set . 另外,还有std::unordered_set

  1. Did I understand the documentation incorrectly and std::set is instead value ordered ? 我是否对文档的理解不正确,而std::set而是按值排序的
  2. And what's std::unordered_set for then? 那么什么是std::unordered_set
  3. Is there a different standard library container that fulfils my requirements? 是否有其他符合我要求的标准库容器?

Did I understand the documentation incorrectly and std::set is instead value ordered? 我是否对文档理解不正确,而std :: set是按值排序的?

It is indeed ordered by value. 它确实是按值排序的。 Unless you provide your own comparator, they are ordered by comparing them using std::less . 除非您提供自己的比较器,否则将通过使用std::less比较它们来对它们进行排序。 For most types, this uses < . 对于大多数类型,它使用< For pointers (which can't generally be compared with < in a well-defined way), it defines an unspecified but consistent ordering. 对于指针(通常无法以明确定义的方式将其与<进行比较),它定义了未指定但一致的顺序。 (On common platforms with a linear address space, this would probably simply compare address values; but you can't rely on that). (在具有线性地址空间的常见平台上,这可能只是比较地址值;但是您不能依赖它)。

So in this case, storing pointers to local variables, it depends on where the compiler chooses to allocate storage for each variable, which could vary from compiler to compiler. 因此,在这种情况下,存储指向局部变量的指针,取决于编译器选择在何处为每个变量分配存储,这可能因编译器而异。

And what's std::unordered_set for then? 那么什么是std::unordered_set

When you don't care about the order, this can give better performance. 当您不关心订单时,这可以提供更好的性能。 It uses a hash table to give constant-time lookup, while set uses a search tree (or something similar) to give logarithmic-time lookup. 它使用哈希表进行恒定时间查找,而set使用搜索树(或类似方法)进行对数时间查找。

Is there a different standard library container that fulfils my requirements? 是否有其他符合我要求的标准库容器?

No, there's no container that both maintains insertion order, and provides fast value-based lookup. 不,没有容器既可以维护插入顺序,又可以提供基于值的快速查找。 Depending on your exact requirements, you might use vector to maintain the order, and put up with a linear-time lookup using std::find ; 根据您的确切要求,您可以使用vector来维持顺序,并使用std::find进行线性时间查找。 or you might use two containers, one to maintain the order and one to provide fast lookup, with careful logic to keep them consistent. 或者您可以使用两个容器,一个用于维护顺序,一个用于提供快速查找,并具有谨慎的逻辑以使它们保持一致。

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

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