1

How can we remove elements from a set like below which has iterator as part of its key? .erase() throws error saying no matching member function for call to 'erase'. Just like emplace() can be used for inserting tuples, what can be used for erasing a tuple from a set instead of directly providing iterator?

list<int> v;

static constexpr auto cmp = [](pair<int, list<int>::iterator > a, pair<int, list<int>::iterator > b)
{
    return a.first < b.first;
};
set< pair<int, list<int>::iterator >, decltype(cmp) > Set{cmp};
v.push_back(1);
Set.emplace( 1, v.rbegin() ); //  Works
Set.erase( make_pair(1, v.rbegin() ) ); // Throws error

Error

Line 23: Char 13: error: no matching member function for call to 'erase' Set.erase( make_pair(val, v.rbegin() ) ); ~~~~^~~~~ /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_set.h:654:7: note: candidate function not viable: no known conversion from 'pair<typename __decay_and_strip<int &>::__type, typename __decay_and_strip<reverse_iterator<_List_iterator<int>>>::__type>' (aka 'pair<int, std::reverse_iterator<std::_List_iterator<int>>>') to 'std::set<std::pair<int, std::_List_iterator<int>>, const MaxStack::(lambda at prog_joined.cpp:10:33), std::allocator<std::pair<int, std::_List_iterator<int>>>>::const_iterator' (aka '_Rb_tree_const_iterator<std::pair<int, std::_List_iterator<int>>>') for 1st argument erase(const_iterator __position) ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_set.h:684:7: note: candidate function not viable: no known conversion from 'pair<[...], typename __decay_and_strip<reverse_iterator<_List_iterator<int>>>::__type>' to 'const pair<[...], std::_List_iterator<int>>' for 1st argument erase(const key_type& __x) ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_set.h:706:7: note: candidate function not viable: requires 2 arguments, but 1 was provided erase(const_iterator __first, const_iterator __last) ^

Context : I am trying to create a datastructure where I receive a stream of elements and I need to store the order of the stream as well as be able to retrieve or erase the maximum element at any point.

Bharat MV
  • 23
  • 8

1 Answers1

0

The problem with this code is that your pair uses list::iterator but you try initializing it with rbegin() which returns objects of type reverse_iterator. Here is the consistent version that compiles.

Having said that, I suggest adding some context to the question and maybe we can suggest a simpler solution that will not require navigating through template complexities.

Roman
  • 1,351
  • 11
  • 26
  • Added the context, hope it helps. Please suggest if you have better ideas of achieving it. Thanks. – Bharat MV Nov 08 '21 at 07:44
  • what does it mean "store the order of the stream" ? In any case, please accept my answer if it fixed your compilation problem. – Roman Nov 09 '21 at 08:18