2017-09-26 46 views
2

我认为以下减少的C++ 11代码应该是有效的。g ++编译器错误对已删除赋值操作符<string,string>

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

但是它失败克++ 6.3编译,抱怨的std ::对已删除的赋值运算符,但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错误还是代码真的无效,出于某种原因,我看不到?

回答

3

std::pair<const string, string>确实已删除了赋值运算符,因为您不能更改first

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

+0

不能在我自己的答案上提出你:感谢编辑,确实is_assignable需要分配类型和受托人。 – spectras

3

让我们看看remove_if文档:

类型提领ForwardIt必须满足的MoveAssignable要求。

即,“给定tT类型和rvT类型的右值表达的修改的左值表达式,表达式t = rv必须是有效的,并[表现为预期]”。

在这里,你通过unordered_map<string, string>的迭代器到remove_if。我们来看一下。据unordered_map documentation

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不能在这些迭代器上使用。

因此,这会使您的代码无效。

+0

这两个答案很好地补充对方,不幸的是我不能接受这两个答案,所以我接受了总结,但也投票了。 –

+0

Caleth的答案很好,因为它更简洁,解释了为什么标准选择了我在我的方法中遵循的方法。感谢您的意图:) – spectras