remove_if() 编译错误

Posted

技术标签:

【中文标题】remove_if() 编译错误【英文标题】:remove_if() compilation error 【发布时间】:2011-12-19 19:59:28 【问题描述】:

VS2010编译错误:

c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm(1840): error C2678: binary '=' : no operator found which take a left-hand operand of type 'const triangle' (or there是不可接受的转换) h:\kingston_backup\ocv\ocv\delaunay.h(281): 可能是 'triangle &triangle::operator =(const triangle &)' 在尝试匹配参数列表“(常量三角形,常量三角形)”时 c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm(1853) :请参阅正在编译的函数模板实例化 '_FwdIt std::_Remove_if,_Pr>(_FwdIt,_FwdIt,_Pr)' 的参考 和 [ _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) : 请参阅正在编译的函数模板实例化 '_FwdIt std::remove_if,triangleIsCompleted>(_FwdIt,_FwdIt,_Pr)' 的参考 和 [ _FwdIt=std::_Tree_const_iterator,std::allocator,true>>>, _Mytree=std::_Tree_val,std::allocator,true>>, _Pr=triangleIsCompleted ]

我认为问题在于将参​​数传递给 STL 的 remove_if(),正如编译器错误所建议的那样。我在该行中添加了以下注释:

//**** 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
    // ...

【问题讨论】:

什么是triangleSet?也许是typedef std::set<const triangle>triangleSet::begin()triangleSet::end() 方法似乎返回 const 迭代器,因此您无法修改集合。 typedef multiset triangleSet; // 三角形集合 incase 的类型 def 给出了任何线索 【参考方案1】:

remove_if 不会删除任何东西(在擦除的意义上)。它复制周围的值,以便所有剩余的值都在范围的开头(并且范围的其余部分处于或多或少未指定的状态)。

由于关联容器中的键是不可变的,因此无法在集合中将值从一个位置复制到另一个位置,因此remove_if 无法使用。

标准库似乎不包含用于 set 的 remove_if,因此您必须自己滚动。它可能看起来像这样:

#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;
        
    

【讨论】:

以上是关于remove_if() 编译错误的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 remove_if 从向量中删除元素

Linux编译错误

Arduino编译错误

我要完整的DELPHI编译错误信息。

SOPC 中NIOSII IDE编译工程时错误!!

C++编译链接错误