对<string,string>的已删除赋值运算符的g ++编译器错误

时间:2017-09-26 08:11:52

标签: c++11 stl

我认为以下简化的C ++ 11代码应该是有效的。

unordered_map<string,string> test;
auto it = remove_if( test.begin(), test.end(),
    [] (const decltype(test)::value_type &entry) { return true; } );

但它无法使用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);

这是一个编译器/ glibc错误,还是因为某些原因导致代码无效?我无法看到?

2 个答案:

答案 0 :(得分:3)

让我们看一下remove_if文档:

  

取消引用的ForwardIt类型必须符合MoveAssignable的要求。

即,给定t,类型Trv的可修改左值表达式,类型T的右值表达式,表达式t = rv必须有效且[按预期行事]“。

在这里,您将unordered_map<string, string>的迭代器传递给remove_if。我们来看看吧。根据{{​​3}},

  

value_type定义为std::pair<const Key, T>

所以,std::pair<const string, string>

让我们看一下对unordered_map documentation。最值得注意的是:

  除非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&>不会参与重载决策。

此处operator=不成立,因此运算符不可用。因此,该货币对不是MoveAssignable。因此remove_if不能用于那些迭代器。

这会使你的代码无效。

答案 1 :(得分:3)

std::pair<const string, string> 删除了分配运算符,因为您无法更改first

STL中所有类似地图的容器的key_type都是const,因为否则你可能会破坏元素的查找。