2
votes

Compilation error in VS2010:

c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm(1840): error C2678: binary '=' : no operator found which takes a left-hand operand of type 'const triangle' (or there is no acceptable conversion)
h:\kingston_backup\ocv\ocv\delaunay.h(281): could be 'triangle &triangle::operator =(const triangle &)'
while trying to match the argument list '(const triangle, const triangle)'

c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm(1853) : see reference to function template instantiation '_FwdIt std::_Remove_if,_Pr>(_FwdIt,_FwdIt,_Pr)' being compiled
with
[
  _FwdIt=std::_Tree_unchecked_const_iterator,std::allocator,true>>>,
  _Mytree=std::_Tree_val,std::allocator,true>>,
  _Pr=triangleIsCompleted
]

h:\kingston_backup\ocv\ocv\delaunay.cpp(272) : see reference to function template instantiation '_FwdIt std::remove_if,triangleIsCompleted>(_FwdIt,_FwdIt,_Pr)' being compiled
with
[
  _FwdIt=std::_Tree_const_iterator,std::allocator,true>>>,
  _Mytree=std::_Tree_val,std::allocator,true>>,
  _Pr=triangleIsCompleted
]

I think the problem is in passing the arguments to the remove_if() of the STL, as suggested by the compiler error. I have added the following comment to the line:

//**** ERROR LINE

class triangleIsCompleted
{
public:
    triangleIsCompleted(cvIterator itVertex, triangleSet& output, const vertex SuperTriangle[3])
        : m_itVertex(itVertex)
        , m_Output(output)
        , m_pSuperTriangle(SuperTriangle)
    {}

    bool operator()(const triangle& tri) const
    {
        bool b = tri.IsLeftOf(m_itVertex);

        if (b)
        {
            triangleHasVertex thv(m_pSuperTriangle);
            if (! thv(tri)) m_Output.insert(tri);
        }
        return b;
    }
};

// ...

triangleSet workset;
workset.insert(triangle(vSuper));

for (itVertex = vertices.begin(); itVertex != vertices.end(); itVertex++)
{
    tIterator itEnd = remove_if(workset.begin(), workset.end(), triangleIsCompleted(itVertex, output, vSuper)); //**** ERROR LINE
    // ...
}
1
What is triangleSet? Maybe it is typedef std::set<const triangle>? It seems that the methods triangleSet::begin() and triangleSet::end() return const iterators, therefore you cannot modify the set.Ferdinand Beyer
typedef multiset<triangle> triangleSet; // the type def for triangle set incase gives any cluepuneetk

1 Answers

5
votes

remove_if does not remove anything (in the sense of erasing). It copies values around, so that all remaining values end up at the beginning of the range (and the rest of the range is in a more or less unspecified state).

Since keys in an associative container are immutable, it is not possible to copy values from one place to another within a set, so remove_if can't work for it.

The standard library does not seem to contain remove_if for set, so you'd have to roll your own. It might look like this:

#include <set>

template <class Key, class Compare, class Alloc, class Func>
void erase_if(std::set<Key, Compare, Alloc>& set, Func f)
{
    for (typename std::set<Key, Compare, Alloc>::iterator it = set.begin(); it != set.end(); ) {
        if (f(*it)) {
            set.erase(it++); //increment before passing to erase, because after the call it would be invalidated
        }
        else {
            ++it;
        }
    }
}