问题描述
如何在unordered_map中使用变体作为键?
例如,我想使以下代码起作用。
using VariantType = std::variant<int,std::string,unsigned int>;
std::unordered_map<VariantType,int,$some_hash_function$> m;
如何实现$ some_hash_function $?
解决方法
已经有一个变体的哈希模板专门化:
http://en.cppreference.com/w/cpp/utility/variant/hash
唯一的条件是,变体中的每个类型都必须具有哈希函数:
如果
std::hash<std::variant<Types...>>
中的每个特殊化都已启用,则特殊化std::hash<std::remove_const_t<Types>>...
被启用(请参阅std :: hash)。否则,则被禁用。
但是所有变量类型都有默认哈希,因此,对于变量类型,由于标准哈希有效,因此无需第三个参数即可进行编译。但是,如果您的变体中的某个类型没有哈希函数(或==运算符),那么它将无法编译,并显示以下错误:
错误:静态声明失败:哈希函数必须可调用且键类型为参数
回到您的问题:
当变体类型具有哈希函数时:
#include <variant>
#include <unordered_map>
#include <string>
#include <iostream>
using VariantType = std::variant<int,std::string,unsigned int>;
std::unordered_map<VariantType,int> m =
{
{1,1},{2u,2},{std::string("string"),3}
};
int main()
{
VariantType v = std::string{"string"};
std::cout << m[v];
}
您将获得以下输出:
Program returned: 0
Program stdout
3
当不是所有的变体类型都具有哈希函数时:
#include <variant>
#include <unordered_map>
#include <string>
#include <iostream>
class UnhashedClass {};
using VariantType = std::variant<UnhashedClass,int,std::string>;
std::unordered_map<VariantType,3}
};
int main()
{
VariantType v = std::string{"string"};
std::cout << m[v];
}
您将获得以下输出:
Could not execute the program
Compiler returned: 1
Compiler stderr
...
error: static assertion failed: hash function must be invocable with an argument of key type
...
您可以在这里自己尝试: