Opened 11 years ago

Closed 11 years ago

#6237 closed Bugs (invalid)

unordered_set behaves differently from 1.46 to 1.48

Reported by: Chris Meyer <cmeyer1969+boost@…> Owned by: Daniel James
Milestone: To Be Determined Component: unordered
Version: Boost 1.48.0 Severity: Regression
Keywords: Cc:

Description

The following code runs OK on 1.46 but fails on 1.48. The correct output is "1".

// gcc -Iboost -lstdc++ test1.cpp                                                                                                                               

#include <iostream>
#include <boost/smart_ptr.hpp>
#include <boost/unordered_set.hpp>

namespace ns {

  typedef boost::shared_ptr<class c> cptr;
  typedef boost::unordered_set<cptr> cset;

  class c
  {
  public:
    c() { }
  };

  bool operator==(const cptr &c1, const cptr &c2) { return true; }
}

int main(int argc, char **argv)
{
  ns::cptr bb1(new ns::c());
  ns::cptr bb2(new ns::c());
  ns::cset cs;
  cs.insert(boost::dynamic_pointer_cast<ns::c>(bb1));
  cs.insert(boost::dynamic_pointer_cast<ns::c>(bb1));
  cs.insert(boost::dynamic_pointer_cast<ns::c>(bb2));
  cs.insert(boost::dynamic_pointer_cast<ns::c>(bb2));
  std::cout << "This should be 1: " << cs.size() << std::endl;
}

I'm using Xcode 4.2 / gcc on 10.6.8.

i686-apple-darwin10-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.1.00)

Change History (3)

comment:1 by anonymous, 11 years ago

No, it's valid, you're using a custom operator== so for it to work you need to use a custom hash function. For this case,:

bool operator==(const cptr &c1, const cptr &c2) { return true; }
// Since cptr is always equal just hash to the same value.
std::size_t hash_value(const cptr& c1) { return 1; }

The hash function for your real code depends on what your equality operator does. This only worked before because there was a bug for hashing shared_ptr so they all went into the same bucket. This worked but was very inefficient.

comment:2 by Chris Meyer <cmeyer1969+boost@…>, 11 years ago

Thanks for the explanation. This seems like a dangerous and non-obvious pitfall.

For reference, the documentation I missed is here:

http://www.boost.org/doc/libs/1_48_0/doc/html/unordered/hash_equality.html

This bug can be closed now.

comment:3 by anonymous, 11 years ago

Resolution: invalid
Status: newclosed
Note: See TracTickets for help on using tickets.