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

时间:2014-09-18 16:51:02

标签: c++ c++11 stl containers stdset

我希望std::set的顺序与std::liststd::vector保持一致,只是第二次不会附加值。 MSVC 110证明我错了。我期望下面的代码得到如下所示的结果,这是在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

在Visual Studio 2012中运行代码会产生您在下面看到的内容。

0
0
2
1
0
2

现在,为什么我会将std::set表现得如上所述?因为cplusplus.com声明

  

集合是按特定订单存储唯一元素的容器。

此外,还有std::unordered_set

  1. 我是否错误地理解了文档,std::set值排序
  2. 当时的std::unordered_set是什么?
  3. 是否有符合我要求的不同标准库容器?

1 个答案:

答案 0 :(得分:2)

  

我是否错误地理解了文档并且std :: set是值命令?

确实按价值排序。除非您提供自己的比较器,否则通过使用std::less进行比较来对它们进行排序。对于大多数类型,这使用<。对于指针(通常不能以明确定义的方式与<进行比较),它定义了一个未指定但一致的排序。 (在具有线性地址空间的通用平台上,这可能只是比较地址值;但您不能依赖它)。

因此,在这种情况下,存储指向局部变量的指针,它取决于编译器选择为每个变量分配存储的位置,这可能因编译器而异。

  

当时的std::unordered_set是什么?

当您不关心订单时,这可以提供更好的性能。它使用哈希表来提供常量时间查找,而set使用搜索树(或类似的东西)来进行对数时间查找。

  

是否有符合我要求的不同标准库容器?

不,没有容器可以维护插入顺序,并提供快速的基于值的查找。根据您的具体要求,您可以使用vector维护订单,并使用std::find进行线性时间查找;或者您可以使用两个容器,一个用于维护订单,一个用于提供快速查找,并使用谨慎的逻辑来保持一致。