Цель шаблона функции ниже - взять любой unordered_map
и создать новый unordered_map
с инвертированными key_type
и mapped_type
.Функция ниже работает для std::unorderd_map
.Я хотел бы, чтобы он работал дополнительно для EITHER std::unordered_map
и любого аналога sth hashmap.
Дополнительное преимущество, которое я хотел бы сохранить, заключается в том, что при вызове функции, если требуется поведение по умолчанию, auto inversion = InvertHashMap(someIntStringMap)
работает без аргументов шаблона.Тем не менее, если я предоставлю действительные исходные аргументы шаблона, я могу переопределить хеш-код по умолчанию, например, используемый для построения инвертированной карты.
У меня возникли серьезные трудности с созданием контейнера общего назначения, хотя я по-прежнему предоставляю шаблон по умолчаниюаргументы, основанные на 5 шаблонных аргументах этого контейнера.Как только я сделаю сам контейнер аргументом шаблона, произойдет сбой разрешения перегрузки и не удастся выполнить компиляцию.
Я развлекался, делая ассоциативный контейнер единственным аргументом шаблона, но затем возможность влиять на аргументы шаблона выходного контейнерапотеряны, по крайней мере, в том смысле, в каком они могут быть явно заданы в моем негибком примере.
#include <unordered_map>
#include <utility>
#include <functional>
#include <memory>
template <typename InKeyType,
typename InValueType,
typename InHasher,
typename InEq,
typename InAlloc,
typename OutHash = std::hash<InValueType>,
typename OutEq = std::equal_to<InValueType>,
typename OutAlloc=std::allocator<std::pair<constInValueType,InKeyType>>>
std::unordered_map<InValueType, InKeyType, OutHash, OutEq, OutAlloc>
InvertMap(const std::unordered_map<InKeyType, InValueType, InHasher, InEq, InAlloc>& source)
{
std::unordered_map<InValueType, InKeyType, OutHash, OutEq, OutAlloc> outMap;
for (const auto& sourceKVPair : source)
outMap[std::get<1>(sourceKVPair)] = std::get<0>(sourceKVPair);
return outMap;
}
//in a .cpp
unordered_map<int,string> um;
auto newUM = InvertHashMap(um); //works well; newUM::key_type is string
Я хотел бы иметь возможность звонить InvertMap(aIntStringUnorderedMap)
и ТАКЖЕ InvertMap< int, string, hash<int>, ..., MyCustomStringHasher>(aIntStringHashMapLikeClass)//producing a HashMapLikeClass<string,int, MyCustomStringHasher,...defaults>
TLDR: Как ввести аргументированный контейнер в шаблон, а также в параметры его шаблона без изменения семантики сайта вызова?
Редактировать.Это моя попытка использовать контейнер в качестве единственного аргумента шаблона.
template <typename AssocCont>
auto InvertCompliantHashMapThatIsntSTDUnorderedMap(const AssocCont&)
{
typedef typename AssocCont::key_type InKeyType;
typedef typename AssocCont::mapped_type InMappedType;
typedef typename AssocCont::value_type InPairConstruct;
typedef typename AssocCont::hasher InHasher;
typedef typename AssocCont::key_equal InEq;
//...
}
//But now there is no external means of desginating the new container's hasher,equality functor etc...
//And as it turns out, I cant even instantiate a new return object from AssocCont<InKeyType,InMappedType> since it is a distinct and unknown type
AssocCont<InMappedType,InKeyType> outmap = AssocCont<InMappedType,InKeyType>(); // nope. equivalent to object<key,value><otherkey,othervalue>()
ДВОЙНОЕ РЕДАКТИРОВАНИЕ: в спешке, чтобы привести пример, я выбрал std::map
в качестве альтернативного примера параметра, который, как я понимаю, не делает 'У меня нет ни хэша, ни пяти аргументов шаблона.Таким образом, основа моего вопроса все еще пытается диверсифицировать эту функцию, но специально для аргументов, которые имеют пять собственных шаблонных аргументов с совместимым поведением ... .Я отредактировал свой пост, чтобы смягчить этот недосмотр.