unordered_set :: remove_if():C3892:无法分配给const变量

时间:2013-03-30 08:44:19

标签: c++

我的代码如下:

unordered_set<AttrValue> output;
...

auto requiredType = variables.at(arg.value);
auto end = remove_if(output.begin(), output.end(), 
    [&](AttrValue x) {
        return !matchingOutputType(requiredType, ast->getNodeType(ast->getNodeKeyAttribute(x)));
    }); // queryevaluator_getcandidatelist.cpp(179)
output.erase(end);

错误在代码的第4行。所以我认为这是因为remove_if。但什么是错的?输出没有定义常量?


Error   90  error C3892: '_Next' : you cannot assign to a variable that is const    c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm    1840
Error   109 error C3892: '_Next' : you cannot assign to a variable that is const    c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm    1840

输出窗口:

3>c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm(1840): error C3892: '_Next' : you cannot assign to a variable that is const
3>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm(1853) : see reference to function template instantiation '_FwdIt std::_Remove_if<std::_List_unchecked_const_iterator<_Mylist>,_Pr>(_FwdIt,_FwdIt,_Pr)' being compiled
3>          with
3>          [
3>              _FwdIt=std::_List_unchecked_const_iterator<std::_List_val<int,std::allocator<AttrValue>>>,
3>              _Mylist=std::_List_val<int,std::allocator<AttrValue>>,
3>              _Pr=`anonymous-namespace'::<lambda4>
3>          ]
3>          h:\dropbox\sch\cs3202\code\source\query\query evaluator\queryevaluator_getcandidatelist.cpp(179) : see reference to function template instantiation '_FwdIt std::remove_if<std::_List_const_iterator<_Mylist>,`anonymous-namespace'::<lambda4>>(_FwdIt,_FwdIt,_Pr)' being compiled
3>          with
3>          [
3>              _FwdIt=std::_List_const_iterator<std::_List_val<int,std::allocator<AttrValue>>>,
3>              _Mylist=std::_List_val<int,std::allocator<AttrValue>>,
3>              _Pr=`anonymous-namespace'::<lambda4>
3>          ]

2 个答案:

答案 0 :(得分:5)

根据标准§23.2.4.6

  

对于关联容器,其值类型与   key类型,iterator和const_iterator都是常量迭代器。

所以,你甚至不能做

std::unordered_set<int> s{1, 2, 3, 4};
*s.begin() = 42;

当然,您无法使用std::remove_if(ForwardIt first, ForwardIt last, ...)功能删除std::setstd::unordered_set中的元素:

  

解除引用的ForwardIt类型必须符合MoveAssignable的要求。

答案 1 :(得分:0)

算法std::remove_if成员函数unordered_set::remove_if,标题中提到但不存在)实际上并不删除任何内容;它通过覆盖与传入标准匹配的元素和序列中的后续元素来重新排序序列。所以它需要一系列可变对象。由unordered_set管理的序列中的对象不可变,因为修改它们可能会破坏容器强加的顺序。

要删除具有给定键的元素,请使用unordered_set::erase

要删除符合更一般标准的元素,您必须自己滚动:遍历容器以查找匹配项(std::find_if将执行此操作),并在找到元素时删除它们使用unordered_set::erase。注意:在擦除元素后,指向它的迭代器不再有效,因此您的代码必须保存指向序列中下一个元素的迭代器。有很多关于如何做到这一点的例子。