Date: Sun, 24 May 2026 20:19:54 -0700
Hi everyone,
std::flat_map' <https://en.cppreference.com/cpp/container/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;
If there is interest, I'd be happy to prepare a draft proposal. I expect
this change may cause some ABI issues, though it may not matter (even if
you can create std::flat_map<int, bool> as in libstdc++, you can't do
anything useful with it).
Thanks,
Aryan Naraghi
std::flat_map' <https://en.cppreference.com/cpp/container/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;
If there is interest, I'd be happy to prepare a draft proposal. I expect
this change may cause some ABI issues, though it may not matter (even if
you can create std::flat_map<int, bool> as in libstdc++, you can't do
anything useful with it).
Thanks,
Aryan Naraghi
Received on 2026-05-25 03:20:09
