可变参数模板包作为 std::unordered_map 的键

Variadic template pack as a key for std::unordered_map

本文关键字:unordered map 的键 std 参数 变参 包作      更新时间:2023-10-16

有没有办法在std::unordered_map中使用可变参数模板作为键模板参数?

我尝试以这种方式执行此操作:

template<typename T, typename ...Args>
class Wrapper {
public:
// some staff
private:
unordered_map<Args, T> hashmap;
};

但是得到这个错误:

错误 C3520"Args":必须在此上下文中扩展参数包

有没有办法在 std::unordered_map 中使用可变参数模板作为键模板参数?

不,据我所知:std::unordered_map需要单个键类型和单个值类型。

但是如果你的意图是有一个hashmap,在Wrapper类中,对于Args...中的每个类型,并且如果Args...类型都不同,你可以通过另一个继承和另一个包装级别来获得它

template <typename K, typename V>
struct wrpH
{ std::unordered_map<K, V> hashmap; };
template <typename T, typename ...Args>
class Wrapper : public wrpH<Args, T>...
{ };

这个解决方案的问题在于你在同一class中有更多的hashmap,要访问它们,你必须显式化相应的基本struct;

如下
w.wrpH<Args, T>::hashmap[argsValue] = tValue;

以下是完整的工作示例

#include <iostream>
#include <unordered_map>
template <typename K, typename V>
struct wrpH
{ std::unordered_map<K, V> hashmap; };
template <typename T, typename ...Args>
class Wrapper : public wrpH<Args, T>...
{ };
int main()
{
Wrapper<int, int, long, long long>  w;
w.wrpH<long, int>::hashmap[1L] = 2;
std::cout << w.wrpH<int, int>::hashmap.size() << std::endl;
std::cout << w.wrpH<long, int>::hashmap.size() << std::endl;
std::cout << w.wrpH<long long, int>::hashmap.size() << std::endl;
}

相反,如果您需要一个具有所有Args...类型组合的键的单个hashmap,则可以使用接收可变参数类型列表的类作为键类型。正如评论中所建议的,std::tuple是显而易见的选择

std::unordered_map<std::tuple<Args...>, T> hashmap;

如果Args...中的某些类型重合,这也有效。