I'm looking to build a compile-time read only map and was hoping to back it with a std::array or std::tuple where each element is a std::pair. For ease of use, I would like to avoid having to annotate every entry at construction, and I'd like it to deduce the number of elements in the map i.e.:
constexpr MyMap<int, std::string_view> my_map{
{1, "value1"},
{2, "value2"},
};
I've tried a number of strategies to do this, but I seem to be getting stuck in making a ctor or function that is able to both accept an arbitrary number of elements and also tell the compiler that all the braced entries being passed (e.x. {1, "value1"}) is a pair, otherwise it cannot deduce the type.
For example:
template <typename Key, typename Mapped, typename... Args>
constexpr auto make_map(std::pair<Key, Mapped>&& first, Args&&... args) {
if constexpr (sizeof...(Args) == 0) {
return std::tuple{std::forward<decltype(first)>(first)};
}
return std::tuple_cat(
std::tuple{std::forward<decltype(first)>(first)},
make_map(std::forward<Args>(args)...)
);
}
It seems like I could make a macro that would quickly allow me to make versions of the function for say all arguments up to a reasonable number (say 10-15) but this feels uglier and worse.
Is there a way to do what I want, or do I need to resort to macros or making users annotate each entry with std::pair?