Я пытаюсь создать std::map
варианта к варианту с отображением от KeyType
до MappedType
.
. Это работает для примерно 100 типов ключей или около того: https://coliru.stacked-crooked.com/a/3959534e4fa38caa. Когда я пытаюсь скомпилировать с 200 типами ключей, G CC некоторое время задумывается, а затем сдается с ошибкой:
g++: internal compiler error: Killed (program cc1plus)
Я считаю, что это может быть проблема из-за слишком большого пакета параметров , Есть ли более масштабируемое решение?
Я включаю ниже значимые части решения:
template<typename Key, typename T>
struct TypeMap {
using KeyType = Key;
using MappedType = T;
};
template<typename>
constexpr bool false_v = false;
// End case
template<typename Key, typename...>
struct MappedTypeForKey {
static_assert(false_v<Key>, "Container mapping for key type not found");
};
// Recursive case
template<typename Key, typename MapKey, typename T, typename... TypeMaps>
struct MappedTypeForKey<Key, TypeMap<MapKey, T>, TypeMaps...> : MappedTypeForKey<Key, TypeMaps...> {
};
// Match case
template<typename Key, typename T, typename... TypeMaps>
struct MappedTypeForKey<Key, TypeMap<Key, T>, TypeMaps...> {
using Type = T;
};
template<typename... TypeMaps>
struct VariantTypeMapImpl {
using KeyType = std::variant<typename TypeMaps::KeyType...>;
using MappedType = std::variant<typename TypeMaps::MappedType...>;
template<typename Key>
using TypeForKey = typename MappedTypeForKey<Key, TypeMaps...>::Type;
};
// This is the key part of the code, allowing a developer to extend the map variants
// at the same time as defining the type mappings:
using VariantTypeMap = VariantTypeMapImpl<
TypeMap<FrogKey, Frog>,
TypeMap<CatKey, Cat>
>;
class VariantMap {
public:
size_t size() const { return map_.size(); }
template<typename Key>
void insert(Key key, VariantTypeMap::TypeForKey<Key> value)
{
map_.emplace(std::move(key), std::move(value));
}
template<typename Key>
const VariantTypeMap::TypeForKey<Key>& get(const Key& key) const
{
return std::get<VariantTypeMap::TypeForKey<Key>>(map_.at(key));
}
private:
std::map<VariantTypeMap::KeyType, VariantTypeMap::MappedType> map_;
};