std::flat_map's KeyContainer and MappedContainer default to std::vector<Key> and std::vector<T>, respectively. Because both KeyContainer and MappedContainer must be sequence containers, it is illegal to create a flat_map with Key = bool or T = bool. Example:
// -stdlib=libstdc++: compiles
// -stdlib=libc++: fails with static assertion ("vector<bool> is not a sequence container")
std::flat_map<int, bool> my_map;
// -stdlib=libstdc++: now fails to compile (can't return bool&)
my_map[1] = true;
[...]
This is verbose for a fairly common use case and unapproachable for new C++ developers. Some of the generated errors are quite hard for a beginner to understand (even with libc++'s static assertion).
Is there anything in flight to address this? If not, is this worth pursuing?
FWIW, I found it super easy to implement a proper `flat_map` that Just Works for all types (even bool). I've been "shipping" it in my P1144 fork of libc++ since at least January 2023, since before Hui Xie's flat containers were merged to Clang trunk.
These days the patch is reduced to just a few lines on top of Hui's implementation:
I certainly think that all vendors (yes, even libc++!) should ship an implementation of `flat_set` and `flat_map` that Just Works, even with `bool`. I think libc++'s current behavior is deplorable.
Does that mean we need to change the wording of the paper standard? Well, IMHO, vendors should know to Do The Right Thing regardless of whether the paper standard requires it. But changing the paper standard would probably help in practice, so sure, I'd encourage you to go for it.
The trick with the paper standard is that `vector<bool>` isn't a "sequence container"; so either you'll have to figure out how to stretch the definition of "sequence container" to include `vector<bool>`, or you'll have to extend the definition of `flat_set` to include `vector<bool>` as a special case. The former would be more generally useful in the future, but the latter is way easier. For example, your proposal could be as simple as this:—
Modify [flat.set] as follows:
> 7. Any sequence container ([sequence.reqmts]) supporting Cpp17RandomAccessIterator , or vector<bool>, can be used to instantiate flat_set. In particular, vector ([vector]) and deque ([deque]) can be used.
> [Note 3: vector<bool> is not a sequence container. — end note]
[...]
> using reference = value_type& KeyContainer::reference;
> using const_reference = const value_type& KeyContainer::const_reference;