0

I'm trying to find the intersection of 2 multisets of objects using std::set_intersection function.

#include <algorithm>
#include <set>


struct Interval
{
  double bottom;
  double top;
};

struct cmp_interval
{
  bool operator()(Interval a, Interval b) const
  {
    return a.bottom < b.bottom;
  }

}

int main()
{
  std::multiset<Interval, cmp_interval> I1;
  Interval i;
  i.bottom = 20;
  i.top = 30;
  I1.insert(i);

  std::multiset<Interval, cmp_interval> I2;
  I2.insert(i);

  std::multiset<Interval, cmp_interval> I3;
    
  std::set_intersection(I1.begin(), I1.end(), I2.begin(), I2.end(), std::inserter(I3, I3.begin()));
  return 0;
}

When I try to compile it, i get a page of verbose errors that I'm unable to properly understand. I'm still a novice in c++ although i do understand some fundamental concepts. Below is the error log generated,

Starting build...
/usr/bin/g++ -g /home/jamal/Documents/daa_assignment_1/measure.cpp -o /home/jamal/Documents/daa_assignment_1/measure
In file included from /usr/include/c++/9/bits/stl_algobase.h:71,
                 from /usr/include/c++/9/bits/char_traits.h:39,
                 from /usr/include/c++/9/ios:40,
                 from /usr/include/c++/9/ostream:38,
                 from /usr/include/c++/9/iostream:39,
                 from /home/jamal/Documents/daa_assignment_1/measure.cpp:1:
/usr/include/c++/9/bits/predefined_ops.h: In instantiation of ‘constexpr bool __gnu_cxx::__ops::_Iter_less_iter::operator()(_Iterator1, _Iterator2) const [with _Iterator1 = std::_Rb_tree_const_iterator<Interval>; _Iterator2 = std::_Rb_tree_const_iterator<Interval>]’:
/usr/include/c++/9/bits/stl_algo.h:5252:12:   required from ‘_OutputIterator std::__set_intersection(_InputIterator1, _InputIterator1, _InputIterator2, _InputIterator2, _OutputIterator, _Compare) [with _InputIterator1 = std::_Rb_tree_const_iterator<Interval>; _InputIterator2 = std::_Rb_tree_const_iterator<Interval>; _OutputIterator = std::insert_iterator<std::multiset<Interval, cmp_interval> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]’
/usr/include/c++/9/bits/stl_algo.h:5307:48:   required from ‘_OIter std::set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter) [with _IIter1 = std::_Rb_tree_const_iterator<Interval>; _IIter2 = std::_Rb_tree_const_iterator<Interval>; _OIter = std::insert_iterator<std::multiset<Interval, cmp_interval> >]’
/home/jamal/Documents/daa_assignment_1/measure.cpp:338:100:   required from here
/usr/include/c++/9/bits/predefined_ops.h:43:23: error: no match for ‘operator<’ (operand types are ‘const Interval’ and ‘const Interval’)
   43 |       { return *__it1 < *__it2; }
      |                ~~~~~~~^~~~~~~~
In file included from /usr/include/c++/9/bits/stl_algobase.h:67,
                 from /usr/include/c++/9/bits/char_traits.h:39,
                 from /usr/include/c++/9/ios:40,
                 from /usr/include/c++/9/ostream:38,
                 from /usr/include/c++/9/iostream:39,
                 from /home/jamal/Documents/daa_assignment_1/measure.cpp:1:
/usr/include/c++/9/bits/stl_iterator.h:915:5: note: candidate: ‘template<class _IteratorL, class _IteratorR, class _Container> bool __gnu_cxx::operator<(const __gnu_cxx::__normal_iterator<_IteratorL, _Container>&, const __gnu_cxx::__normal_iterator<_IteratorR, _Container>&)’
  915 |     operator<(const __normal_iterator<_IteratorL, _Container>& __lhs,
      |     ^~~~~~~~
/usr/include/c++/9/bits/stl_iterator.h:915:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/9/bits/stl_algobase.h:71,
                 from /usr/include/c++/9/bits/char_traits.h:39,
                 from /usr/include/c++/9/ios:40,
                 from /usr/include/c++/9/ostream:38,
                 from /usr/include/c++/9/iostream:39,
                 from /home/jamal/Documents/daa_assignment_1/measure.cpp:1:
/usr/include/c++/9/bits/predefined_ops.h:43:23: note:   ‘const Interval’ is not derived from ‘const __gnu_cxx::__normal_iterator<_IteratorL, _Container>’
   43 |       { return *__it1 < *__it2; }
      |                ~~~~~~~^~~~~~~~
In file included from /usr/include/c++/9/bits/stl_algobase.h:67,
                 from /usr/include/c++/9/bits/char_traits.h:39,
                 from /usr/include/c++/9/ios:40,
                 from /usr/include/c++/9/ostream:38,
                 from /usr/include/c++/9/iostream:39,
                 from /home/jamal/Documents/daa_assignment_1/measure.cpp:1:
/usr/include/c++/9/bits/stl_iterator.h:922:5: note: candidate: ‘template<class _Iterator, class _Container> bool __gnu_cxx::operator<(const __gnu_cxx::__normal_iterator<_Iterator, _Container>&, const __gnu_cxx::__normal_iterator<_Iterator, _Container>&)’
  922 |     operator<(const __normal_iterator<_Iterator, _Container>& __lhs,
      |     ^~~~~~~~
/usr/include/c++/9/bits/stl_iterator.h:922:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/9/bits/stl_algobase.h:71,
                 from /usr/include/c++/9/bits/char_traits.h:39,
                 from /usr/include/c++/9/ios:40,
                 from /usr/include/c++/9/ostream:38,
                 from /usr/include/c++/9/iostream:39,
                 from /home/jamal/Documents/daa_assignment_1/measure.cpp:1:
/usr/include/c++/9/bits/predefined_ops.h:43:23: note:   ‘const Interval’ is not derived from ‘const __gnu_cxx::__normal_iterator<_Iterator, _Container>’
   43 |       { return *__it1 < *__it2; }
      |                ~~~~~~~^~~~~~~~

Build finished with error(s).
The terminal process failed to launch (exit code: -1).



Any help would be appreciated. Thank you.

Update: From the error log, I see that there's another optional argument that needs to be passed for std::set_intersection for custom comparator.

/usr/include/c++/9/bits/stl_algo.h:5252:12:   required from ‘_OutputIterator std::__set_intersection(_InputIterator1, _InputIterator1, _InputIterator2, _InputIterator2, _OutputIterator, _Compare) [with _InputIterator1 = std::_Rb_tree_const_iterator<Interval>; _InputIterator2 = std::_Rb_tree_const_iterator<Interval>; _OutputIterator = std::insert_iterator<std::multiset<Interval, cmp_interval> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]’

The _Compare parameter looks to be by default __gnu_cxx::__ops::_Iter_less_iter. I want to use comparator class that i have made(cmp_interval) there but it doesn't accept classes.

11
  • You are supposed to overload operator <. Commented Mar 17, 2021 at 19:14
  • @PaulMcKenzie You only need to do that for the default comparator. They have provided a custom comparator. Commented Mar 17, 2021 at 19:17
  • 1
    @Jamāl -- I know you used the operator(), but that is only done when inserting items into the set. It has nothing to do with the set_intersection call. See the previous comment by Francois. You need to tell set_intersection how to compare two items. Commented Mar 17, 2021 at 19:21
  • 1
    Add cmp_interval{} as another argument and it should fix everything. Commented Mar 17, 2021 at 19:24
  • 1
    @Jamāl std::set_intersection needs to know how to compare elements. Since you didn't overload operator< and are using a comparator instead, you need to provide that comparator to std::set_intersection otherwise it doesn't know how to check which elements intersect. Commented Mar 17, 2021 at 19:44

1 Answer 1

2
std::multiset<Interval, cmp_interval> I3;

Here, you specify the type of the comparator, as a type template argument. The actual comparator object is created inside the constructor of the multiset. Now you want to pass a similar object to the std::set_intersection function. Use:

std::set_intersection(I1.begin(), I1.end(), 
                      I2.begin(), I2.end(), 
                      std::inserter(I3, I3.begin()),
                      cmp_interval());

The empty parenthesis in cmp_interval() mean: an unnamed default-constructed object. You could also use cmp_interval{}, since C++11.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.