2017-09-26 50 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