Hi everyone,
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;
To get std::flat_map<int, bool> working, the user must override MappedContainer with a sequence container. Example:
std::flat_map<int, bool, std::less<int>, std::vector<int>, std::deque<bool>> my_map; // Ok
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?
One approach would be to change the std::flat_map definition from:
template<
class Key,
class T,
class Compare = std::less<Key>,
class KeyContainer = std::vector<Key>,
class MappedContainer = std::vector<T>
> class flat_map;
To:
// Note exposition-only helper.
template <class T>
using /*default-flat-map-container*/ = std::conditional_t<
std::is_same_v<T, bool>,
std::deque<bool>,
std::vector<T>>;
template<
class Key,
class T,
class Compare = std::less<Key>,
class KeyContainer = /*default-flat-map-container*/<Key>,
class MappedContainer = /*default-flat-map-container*/<T>
> class flat_map;