我认为以下简化的 C++11 代码应该是有效的。
unordered_map<string,string> test;
auto it = remove_if( test.begin(), test.end(),
[] (const decltype(test)::value_type &entry) { return true; } );
Run Code Online (Sandbox Code Playgroud)
但它无法使用 g++ 6.3 编译,抱怨 std::pair 的赋值运算符已删除,但 AFAIK 未删除该运算符。
/usr/include/c++/6/bits/stl_algo.h:868:16: error: use of deleted function ‘std::pair<_T1, _T2>& std::pair<_T1, _T2>::operator=( ...
*__result = _GLIBCXX_MOVE(*__first);
Run Code Online (Sandbox Code Playgroud)
这是编译器/glibc 错误还是由于某些原因我看不到代码真的无效?
让我们看看remove_if文档:
该型反引用ForwardIt必须满足的要求MoveAssignable。
也就是说,“给定t一个类型为Tand的可修改左值表达式rv,一个类型为 的右值表达式T,该表达式t = rv必须有效并且[行为如预期]”。
在这里,您将unordered_map<string, string>的迭代器传递给remove_if。我们来看一下。根据unordered_map文件,
value_type被定义为std::pair<const Key, T>
所以,std::pair<const string, string>。
让我们看看对的operator=. 最为显着地:
template< class U1, class U2 > pair& operator=( const pair<U1,U2>& other );不参与重载决议,除非std::is_assignable_v<first_type&, const U1&>和std::is_assignable_v<second_type&, const U2&>两者都为真。
在这里,std::is_assignable_v<const string&, const string&>不是真的,因此运营商不可用。因此,该对不是 MoveAssignable。因此remove_if不能用于那些迭代器。
所以这会使您的代码无效。
std::pair<const string, string> 确实已删除赋值运算符,因为您无法更改first.
STL 中所有key_type类似地图的容器的 都是 const,因为否则可能会破坏元素的查找。