Q:

g++ compiler error on deleted assignment operator of pair

I think the following reduced C++11 code should be valid.
unordered_map<string,string> test;
auto it = remove_if( test.begin(), test.end(),
    [] (const decltype(test)::value_type &entry) { return true; } );

But it fails to compile with g++ 6.3, complaining about a deleted assignment operator of std::pair, but AFAIK that operator is not deleted.
/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);

Is this a compiler/glibc bug or is the code really invalid for some reason I fail to see?

A:

Let's look at remove_if documentation:

The type of dereferenced ForwardIt must meet the requirements of MoveAssignable.

That is, “given t, a modifiable lvalue expression of type T and rv, an rvalue expression of type T, the expression t = rv must be valid and [behave as expected]”.
Here, you pass unordered_map<string, string>'s iterator to remove_if. Let's have a look. According to unordered_map documentation,

value_type is defined as std::pair<const Key, T>

So, std::pair<const string, string>.
Let's look at pair's operator=. Most notably:

template< class U1, class U2 >
  pair& operator=( const pair<U1,U2>& other ); does not participate in overload resolution unless std::is_assignable_v<first_type&, const U1&> and std::is_assignable_v<second_type&, const U2&> are both true.

Here, std::is_assignable_v<const string&, const string&> is not true, therefore the operator is not available. Therefore the pair is not MoveAssignable. Therefore remove_if cannot be used on those iterators.
So that would make your code invalid.

A:

std::pair<const string, string> does have deleted assignment operator(s), because you can't change first.
The key_type of all the map-like containers in the STL are const, because otherwise you could break the lookup of elements.

