4

I am trying to compare two sets of C++11 weak_ptr using GCC 4.7.2. The code below shows the smallest possible sample reproducing the error:

std::set<std::weak_ptr<int>, std::owner_less<std::weak_ptr<int> > > set1;
std::set<std::weak_ptr<int>, std::owner_less<std::weak_ptr<int> > > set2;

bool result = (set1 == set2);

Trying to compile the above results in a long list of errors, of which the following is the first actual error:

/usr/include/c++/4.7/bits/stl_algobase.h:791:6: error: no match for ‘operator==’ in ‘__first1.std::_Rb_tree_const_iterator<_Tp>::operator*<std::weak_ptr<int> >() == __first2.std::_Rb_tree_const_iterator<_Tp>::operator*<std::weak_ptr<int> >()’

Due to the transient nature of weak_ptr, is comparing an entire set of them just not possible?

Update:

One suggestion is to use:

bool result = !((set1 < set2) || (set2 < set1))

This results in:

/usr/include/c++/4.7/bits/stl_algobase.h:882:6: error: no match for ‘operator<’ in ‘__first1.std::_Rb_tree_const_iterator<_Tp>::operator*<std::weak_ptr<int> >() < __first2.std::_Rb_tree_const_iterator<_Tp>::operator*<std::weak_ptr<int> >()’
Hans
  • 2,448
  • 2
  • 24
  • 30

1 Answers1

4

Since weak_ptr doesn't support '==', but in this case you can use the comparison operator of the set try:

bool result = !(std::lexicographical_compare(set1.begin(), set1.end(),
                                         set2.begin(), set2.end(),
                                         set1.value_comp()) ||
                std::lexicographical_compare(set2.begin(), set2.end(),
                                         set1.begin(), set1.end(),
                                         set1.value_comp()));

This will test for equivalence, not equality. And it lacks a certain... clarity.

Dave S
  • 20,507
  • 3
  • 48
  • 68
  • I edited my question with a comment on your initial suggestion. I noticed you updated the answer, and I will definitely give it a try. I will leave the original edit for educational purposes. – Hans Dec 19 '12 at 20:00
  • Also, I thought that since I specified std::owner_less as the comparison operator it shouldn't matter whether or not weak_ptr implements '=='? – Hans Dec 19 '12 at 20:01
  • 1
    @Hans: Yeah, I realized after typing it that it's going to fall through to 'operator <', which has the same problem. So changed it to the manual version, which can use the specified comparison operator. Also, my first edit had the spelling a bit off :) – Dave S Dec 19 '12 at 20:02
  • 2
    @Hans: The issue is that the container requirements specify that the '==' operator uses 'std::equal' and '<' uses 'std::lexicographical_compare', but both of those default to using the underlying operator. I would think `std::set` should use the ordering specified by the set, but that's not what it does – Dave S Dec 19 '12 at 20:04