https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115285
--- Comment #14 from Jonathan Wakely <redi at gcc dot gnu.org> ---
We're assuming that an iterator's reference type can be converted to the
key_type. This doesn't compile on trunk:
#include <unordered_set>
struct K {
explicit K(int) noexcept { }
bool operator==(const K&) const { return true; }
};
template<> struct std::hash<K> {
auto operator()(const K&) const { return 0ul; }
};
int i[1];
std::unordered_set<K> s(i, i+1);
This fails for similar reasons:
#include <unordered_map>
struct K {
explicit K(int) noexcept { }
bool operator==(const K&) const { return true; }
};
template<> struct std::hash<K> {
auto operator()(const K&) const { return 0ul; }
};
const std::pair<int, int> p[2]{{1,2}, {3,4}};
std::unordered_map<K, int> m(p, p+2);
This fails because of a missing specialization for const rvalues:
#include <unordered_map>
#include <iterator>
struct Pair
{
explicit operator std::pair<const int, int>() const&& { return {1, 2}; }
};
Pair p2[1];
std::unordered_map<int, int> um(std::make_move_iterator(p2),
std::make_move_iterator(p2+1));
Finally, the _ConvertToValueType<_Select1st, T> specialization needs to handle
all value categories of std::pair arguments.