2

I would like to use std::stable_partition for removing entries from a std::vector. The vector is a member of a template class in some library A. I am trying to setup a struct called Checker with an operator() to act as predicate for std::stable_partition.

My questions seems related to How do I define a sort predicate for a templated container class in C++ but in my case the argument to the predicate depends on the templates (across two DLLs)

Some DLL A:

VectorKey2GenericPtr.h

#include <vector>
#include <set>

template <class KEY_TYPE, class GENERIC_TYPE>
class VectorKey2GenericPtr
{
protected:
    std::vector< std::pair<const KEY_TYPE, GENERIC_TYPE*> > m_Vector;
    std::set<KEY_TYPE> m_keysToBeRemoved;
public:
    void Remove(const std::set<KEY_TYPE>& keysOfEntriesToBeRemoved);
protected:
    struct Checker
    {
      std::set<KEY_TYPE> m_keysToBeRemoved;
      explicit Checker(std::set<KEY_TYPE>& keysToBeRemoved):m_keysToBeRemoved(keysToBeRemoved) {}
      //bool operator() (const std::pair<const KEY_TYPE, GENERIC_TYPE>& pairToBeTested) <-- before fix suggested by @MassimilianoJanes
      bool operator() (const std::pair<const KEY_TYPE, GENERIC_TYPE*>& pairToBeTested)
      {
        const KEY_TYPE& keyToBeTested = pairToBeTested.first;
        typename std::set<KEY_TYPE>::iterator it = m_keysToBeRemoved.find(keyToBeTested);
        bool found = false;
        if (it != m_keysToBeRemoved.end())
        {
          found = true;
          m_keysToBeRemoved.erase(it);
        }
        return found;
      }
    };
};

VectorKey2GenericPtr.cpp

#include "VectorKey2GenericPtr.h"
#include <functional>

template <class KEY_TYPE, class GENERIC_TYPE>
void VectorKey2GenericPtr<KEY_TYPE, GENERIC_TYPE>::
Remove(const std::set<KEY_TYPE>& keysOfEntriesToBeRemoved)
{
  m_keysToBeRemoved = keysOfEntriesToBeRemoved;
  typename std::vector< std::pair<const KEY_TYPE, GENERIC_TYPE*> >::iterator bound;

  // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  // !!!  I would like to use Checker like this: !!!
  bound = std::stable_partition( m_Vector.begin(), m_Vector.end(), Checker(m_keysToBeRemoved) );
  //
  // TODO: Remove one partition from the map
  //
  // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

}

class SomeInterfaceFromDLLB;
template class VectorKey2GenericPtr<int, SomeInterfaceFromDLLB>;

template class VectorKey2GenericPtr<int, SomeInterfaceFromDLLB>::Checker;

some DLL B:

SomeInterfaceFromDLLB.h

class SomeInterfaceFromDLLB{};

EDIT1

After comment by @Massimiliano Janes my original compilation error:

C2079 std::pair<const KEY_TYPE, GENERIC_TYPE>::second uses undefined class `SomeInterfaceFromDLLB'

Has been fixed by changing:

Checker: 'bool operator() (const std::pair& pairToBeTested)`

to

Checker: bool operator() (const std::pair& pairToBeTested)

Now I am still getting the following error:

C2166 l-value specifies const object

This is related to the line:

bound = std::stable_partition( m_Vector.begin(), m_Vector.end(), Checker(m_keysToBeRemoved) );

utility.h:

_Myt& operator=(_Myt&& _Right)
 _NOEXCEPT_OP((is_nothrow_move_assignable<_Ty1>::value && is_nothrow_move_assignable<_Ty2>::value))
  { // assign from moved pair
    first = _STD forward<_Ty1>(_Right.first);
    second = _STD forward<_Ty2>(_Right.second);
    return (*this);
  }

Any suggestions?

Azeem
  • 11,148
  • 4
  • 27
  • 40
DrFlow
  • 53
  • 1
  • 5
  • the checker operator() should take a std::pair not a std::pair, is it a typo ? – Massimiliano Janes Oct 25 '17 at 09:07
  • by the way, if you only want to remove elements from the vector, std::remove_if will be more efficient than std::stable_partition – Massimiliano Janes Oct 25 '17 at 09:10
  • @MassimilianoJanes : Thanks for your comments: 1) Yes, you are right. I corrected it. 2) But I would like to redefined the keys so there are no 'holes' in the numbering. – DrFlow Oct 25 '17 at 10:07
  • @MassimilianoJanes: Thanks for your comments: 1) Fixed the compilation error ! – DrFlow Oct 25 '17 at 10:29
  • `stable_partition` needs to move elements around, in part by assigning new values to existing elements. But elements of your vector are not assignable, by reason of having a `const` member. If you insist on keeping that, your only option is `std::copy_if` or `std::partition_copy` or similar - copying elements into a different vector in the right order. – Igor Tandetnik Oct 25 '17 at 13:26
  • @IgorTandetnik thanks for this explanation. That makes perfectly sense. – DrFlow Oct 26 '17 at 16:00

0 Answers0