https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120432
--- Comment #2 from Arthur O'Dwyer <arthur.j.odwyer at gmail dot com> --- (In reply to Patrick Palka from comment #1) > Confirmed, that fix looks good to me. > > FWIW our template operator[] is just the standard > https://eel.is/c++draft/flat.map#access-4 with more generalized constraints: > > same_as<remove_cvref_t<_Key2>, _Key> || __transparent_comparator<_Compare> > > The intent is to be able to dispatch the non-template overloads to this > template and avoid having to introduce an actual helper function. Yeah, but by giving the non-transparent-comparator flat_map's helper the same name as the actual operator[] of the transparent-comparator flat_map, you end up interfering with overload resolution on the non-transparent-comparator flat_map's operator[]. (Disclosure: I once gave a whole conference talk on "When Should You Give Two Things the Same Name?" My answer was, and remains, "Never gratuitously." :)) > > static_assert(!C<std::flat_map<int, int>, volatile int>); // bogus error > We can fix this by changing remove_cvref_t<K> to > remove_const_t<remove_reference_t<K>> in the constraint, but I don't see why > we'd want to reject this volatile index case? One possible answer is "because the paper standard says so"; libc++ often phrases this pseudo-helpfully as "we don't want to provide extensions because then people will rely on them and get locked into our library, and lock-in is bad." But I think a better answer in this case is "because using a volatile index *will not actually compile*, so flat_map shouldn't gratuitously advertise that signature to SFINAE." https://godbolt.org/z/bdTK7nPKG std::flat_map<int, int> m; volatile int vi = 42; m[vi] = 1; .../flat_map:1155:11: error: no matching member function for call to 'try_emplace' 1155 | { return try_emplace(std::forward<_Key2>(__x)).first->second; } | ^~~~~~~~~~~ <source>:15:6: note: in instantiation of function template specialization 'std::flat_map<int, int>::operator[]<volatile int &>' requested here 15 | m[vi] = 1; | ^