Jamāl
Jamāl

Reputation: 121

std::multiset intersection compilation error

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.

Upvotes: 0

Views: 179

Answers (1)

Armen Tsirunyan
Armen Tsirunyan

Reputation: 133122

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.

Upvotes: 2

Related Questions