<hash_set>等于运算符在VS2010 </hash_set>中不起作用

时间:2010-05-05 11:31:15

标签: c++ visual-studio-2010

示例代码:

std::hash_set<int> hs1; // also i try std::unordered_set<int> - same effect 
std::hash_set<int> hs2;

hs1.insert(15);
hs1.insert(20);

hs2.insert(20);
hs2.insert(15);

assert(hs1 == hs2);

hash_set不会以散列函数定义的某种顺序存储元素......为什么? 请注意,此代码在VS2008中使用stdext :: hash_set。

3 个答案:

答案 0 :(得分:4)

看起来在Visual C ++ 2010中,hash_setunordered_set的等式比较都被打破了。

我使用标准quoted by Matthieu中的语言为无序容器实现了一个天真的相等函数,以验证它是一个错误(只是为了确定):

template <typename UnorderedContainer>
bool are_equal(const UnorderedContainer& c1, const UnorderedContainer& c2)
{
    typedef typename UnorderedContainer::value_type Element;
    typedef typename UnorderedContainer::const_iterator Iterator;
    typedef std::pair<Iterator, Iterator> IteratorPair;

    if (c1.size() != c2.size())
        return false;

    for (Iterator it(c1.begin()); it != c1.end(); ++it)
    {
        IteratorPair er1(c1.equal_range(*it));
        IteratorPair er2(c2.equal_range(*it));

        if (std::distance(er1.first, er1.second) != 
            std::distance(er2.first, er2.second))
            return false;

        // A totally naive implementation of is_permutation:
        std::vector<Element> v1(er1.first, er1.second);
        std::vector<Element> v2(er2.first, er2.second);

        std::sort(v1.begin(), v1.end());
        std::sort(v2.begin(), v2.end());

        if (!std::equal(v1.begin(), v1.end(), v2.begin()))
            return false;
    }

    return true;
}

它会返回您示例中的hs1hs2相等。 (有人告诉我你是否发现了该代码中的错误;我没有真正测试它...)

我将在Microsoft Connect上提交缺陷报告。

答案 1 :(得分:2)

最后在最终草案中找到了参考文献23.2.5,注11:

  

两个无序容器ab比较等于a.size() == b.size(),对于从[Ea1,Ea2)获得的每个等效键组a.equal_range(Ea1),存在等价物-key组[Eb1,Eb2)b.equal_range(Ea1)获得,以便distance(Ea1, Ea2) == distance(Eb1, Eb2)is_permutation(Ea1, Ea2, Eb1)返回true

我敢打赌hash_set现在以unordered_set(开头)的形式实施,但我仍然不明白为什么在你的情况下会失败。

复杂性要求在平均情况下为O(N),但在最坏的情况下退化为O(N 2 ),因为线性链实现要求。

答案 2 :(得分:1)

我问这个问题here但没有回复=) 感谢您的反馈。

我还创建了一些简单的控制台测试(只是为了确定):

#include <iostream>
#include <hash_set>
int main(int argc, char* argv[])
{   
  stdext::hash_set<int> hs1, hs2;
  hs1.insert(10);
  hs1.insert(15);
  hs2.insert(15);
  hs2.insert(10);
  std::cout << ((hs1 == hs2) ? "It works!" : "It NOT works") << std::endl;
  return EXIT_SUCCESS;
}

并编译它。 使用vs2008命令提示符:

cl.exe HashSetTest.cpp /oHashSetTest2008.exe 

使用vs2010命令提示符:

cl.exe HashSetTest.cpp /oHashSetTest2010.exe

我真的看到不同的结果=)