2017-09-26 8 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; }); 

は、しかし、それはのstd ::ペアの削除代入演算子不満、6.3グラム++でコンパイルに失敗しますが、そのオペレータ私の知る限り削除されません。

/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>を変更することができないため、には割り当て演算子が削除されています。

STL内のすべてのマップ状コンテナのkey_typeはconstです。そうしないと、要素の参照が破損する可能性があるためです。

+0

私自身の答えであなたを@mentionできません:編集のおかげで、実際にis_assignableは、割り当てられたタイプと譲受人の両方のタイプが必要です。 – spectras

3

のはremove_ifドキュメントを見てみましょう:

間接参照ForwardItのタイプはMoveAssignableの要件を満たす必要があります。ある

t与え、タイプTrv、タイプTの右辺値発現の変更左辺値発現は、発現t = rvが有効でなければならず、[として期待挙動]」。

ここでは、unordered_map<string, string>のイテレータをremove_ifに渡します。みてみましょう。

value_typeunordered_map documentationによるのでstd::pair<const Key, T>

std::pair<const string, string>として定義されます。

ペアのoperator=を見てみましょう。最も顕著なのは:std::is_assignable_v<first_type&, const U1&>std::is_assignable_v<second_type&, const U2&>が両方とも該当する場合を除き

template< class U1, class U2 > pair& operator=(const pair<U1,U2>& other);は、オーバーロードの解決に参加しません。

ここで、std::is_assignable_v<const string&, const string&>は真ではないため、演算子は使用できません。したがって、ペアはMoveAssignableではありません。したがって、これらのイテレータではremove_ifを使用できません。

これにより、コードが無効になる可能性があります。

+0

2つの答えはうまく補完し合いますが残念ながら私は両方を受け入れることができませんでしたので、要約したものを受け入れましたが、これも投票しました。 –

+0

Calethの答えは、それがより簡潔で、標準がなぜ私が辿ったアプローチを選んだのかという理由から、いいですね。感謝の意向:) – spectras

関連する問題