7

我有如下代码:

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>          ]
4

2 回答 2

8

根据标准§ 23.2.4.6

对于值类型与键类型相同的关联容器,iterator 和 const_iterator 都是常量迭代器。

所以,你甚至做不到

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

而且,当然,您不能使用函数从andstd::remove_if(ForwardIt first, ForwardIt last, ...)中删除元素:std::setstd::unordered_set

解引用的 ForwardIt 类型必须满足 MoveAssignable 的要求。

于 2013-03-30T09:10:37.000 回答
0

The algorithm std::remove_if (not the member function unordered_set::remove_if, which is mentioned in the title but does not exist) doesn't actually remove anything; it reorders the sequence by overwriting elements that match the passed-in criterion with later elements in the sequence. So it requires a sequence of mutable objects. The objects in the sequence managed by an unordered_set are not mutable, since modifying them could disrupt the order that the container imposes.

To remove an element with a given key, use unordered_set::erase.

To remove an element or elements that match a more general criterion, you have to roll your own: iterate through the container looking for a match (std::find_if will do this), and remove elements as they're found using unordered_set::erase. Be careful: after you've erased an element the iterator that points to it is no longer valid, so your code has to save an iterator that points to the next element in the sequence. There are lots of examples of how to do this floating around.

于 2013-03-30T12:41:12.380 回答