remove_if () ошибка компиляции - PullRequest
2 голосов
/ 19 декабря 2011

Ошибка компиляции в 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
]

Я думаю, что проблема заключается в передаче аргументов в remove_if() STL, как предполагает ошибка компилятора.Я добавил следующий комментарий к строке:

//**** 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 Ответ

5 голосов
/ 20 декабря 2011

remove_if ничего не удаляет (в смысле стирания). Он копирует значения вокруг, так что все остальные значения оказываются в начале диапазона (а остальная часть диапазона находится в более или менее неопределенном состоянии).

Поскольку ключи в ассоциативном контейнере являются неизменяемыми, невозможно скопировать значения из одного места в другое в наборе, поэтому remove_if не может работать для него.

Кажется, стандартная библиотека не содержит remove_if для set, поэтому вам придется свернуть свою собственную. Это может выглядеть так:

#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;
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...