gpt4 book ai didi

c++ - 尝试(稍微)概括 C++ 模板。关联容器 key :Value Inversion

转载 作者:行者123 更新时间:2023-11-30 04:56:23 25 4
gpt4 key购买 nike

下面函数模板的目标是取任意unordered_map并产生一个新的unordered_mapkey_typemapped_type倒。下面的函数适用于 std::unorderd_map .我希望它还能为 EITHER std::unordered_map 工作和任何 STL 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。作为替代参数示例,我意识到它没有哈希器,也没有五个模板参数。所以我的问题的基础仍然是试图使这个功能多样化,但特别针对具有五个自己的模板参数且行为兼容的参数......。我已经编辑了我的帖子以减轻这种疏忽。

最佳答案

我觉得这可能会以类似于 standard algorithms library 的方式更好地实现.换句话说,将您的反演函数设计为将一系列迭代器放入输入容器并将迭代器放入输出容器。它将更易于实现并为用户提供更大的灵 active 。此外,只要输入和输出迭代器满足特定条件(可能由 concepts 强加),它就会在某种程度上独立于容器类型。这是一个示例,它可能不是您想要的,但您可以修改它以满足您的需要:

#include <algorithm>
#include <iostream>
#include <map>
#include <string>
#include <unordered_map>

namespace
{
template <class InputIt, class OutputIt>
void inverse_map(InputIt start, InputIt stop, OutputIt d_first)
{
while(start != stop)
{
*d_first = {start->second, start->first} ;
++d_first ;
++start ;
}
}
} // anonymous namespace

int main()
{
std::map<int, std::string> map_1 {{1, "foo"}, {2, "bar"}, {3, "foo"}} ;
std::unordered_map<std::string, int> map_2 ;
//
// Or, you can use:
//
// std::unordered_map<std::string, int, MyCustomHasher> map_2 ;
//

inverse_map(map_1.begin(), map_1.end(), std::inserter(map_2, map_2.end())) ;

for(const auto& [key, value]: map_2) // requires C++17
std::cout << key << ": " << value << "\n" ;

return 0;
}

输出:

bar: 2
foo: 1

在线试用 here .

关于c++ - 尝试(稍微)概括 C++ 模板。关联容器 key :Value Inversion,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52549351/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com