如何在unordered_map中使用变体作为键? [英] How to use variants as the key in unordered_map?

查看:41
本文介绍了如何在unordered_map中使用变体作为键?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在 unordered_map 中使用变体作为键?

How can I use variants as the key in unordered_map?

例如,我想让下面的代码工作.

For example, I'd like to make the following code work.

using VariantType = std::variant<int, std::string, unsigned int>;
std::unordered_map<VariantType, int, $some_hash_function$> m;

如何实现 $some_hash_function$?

How do I implement $some_hash_function$?

推荐答案

已经有一个针对变体的哈希模板特化:

There is already a hash template specialization for variant:

http://en.cppreference.com/w/cpp/utility/variant/hash

唯一的条件是变体中的每个类型都必须有一个哈希函数:

The only condition is that every type in the variant must have a hash function:

特化 std::hash<std::variant<Types...>> 如果 std::hashstd::hash<std::remove_const_t<Types>>... 启用,否则禁用.

The specialization std::hash<std::variant<Types...>> is enabled (see std::hash) if every specialization in std::hash<std::remove_const_t<Types>>... is enabled, and is disabled otherwise.

但是您的所有变体类型都有默认散列,因此,对于您的变体类型,它编译时无需第三个参数,因为标准散列有效.但是,如果您的变体中有一个没有散列函数(或 == 运算符)的类型,那么它将无法编译并出现以下错误:

But all your variant types have default hashes so, for your variant types, it compiles without the third parameter because the standard hash works. However, if you had a type in your variant that did not have a hash function (or an == operator) then it would fail to compile with this error:

错误:静态断言失败:哈希函数必须可以使用键类型的参数调用

error: static assertion failed: hash function must be invocable with an argument of key type

回到你的问题:

当变体类型具有哈希函数时:

When the variant types have hash functions:

#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

当并非所有变体类型都具有哈希函数时:

And when not all the variant types have hash functions:

#include <variant>
#include <unordered_map>
#include <string>
#include <iostream>
class UnhashedClass {};
using VariantType = std::variant<UnhashedClass, int, std::string>;
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];
}

你得到这个输出:

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
...

您可以在这里自己尝试:

You can try it yourself here:

https://godbolt.org/z/bnzcE9

这篇关于如何在unordered_map中使用变体作为键?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆