如何在 unordered_map 中使用向量变体作为键?
How to use a vector variants as key in unordered_map?
如何使用变体向量作为 unordered_map 中的键?
例如,我想让下面的代码工作。
using VariantType = std::variant<int, std::string, unsigned int>;
using VecVariantType = std::vector<VariantType>;
std::unordered_map<VecVariantType, int, $some_hash_function$> m;
如何实施 $some_hash_function$?
我喜欢一个好主意...
除了“我想知道我是否可以编译它和 运行”示例之外,我不知道您如何或为什么将这样的东西用于其他东西。
#include <iostream>
#include <vector>
#include <unordered_map>
#include <variant>
using VariantType = std::variant<int, std::string, unsigned int>;
using VecVariantType = std::vector<VariantType>;
struct Hasher
{
size_t operator()(const VecVariantType &v) const
{
size_t hash = 0;
for (auto &val : v)
{
hash ^= std::hash<VariantType>()(val);
}
return hash;
}
};
std::ostream& operator<<(std::ostream& out, std::pair<const VecVariantType, int> &p)
{
out << "key: { ";
bool needs_comma = false;
for (auto &var : p.first)
{
if (needs_comma)
{
out << ", ";
}
if (std::holds_alternative<int>(var))
{
out << "int: " << std::get<int>(var);
needs_comma = true;
}
if (std::holds_alternative<std::string>(var))
{
out << "string: " << std::get<std::string>(var);
needs_comma = true;
}
if (std::holds_alternative<unsigned int>(var))
{
out << "uint: " << std::get<unsigned int>(var);
needs_comma = true;
}
}
out << " }, value: " << p.second;
return out;
}
void lookup(const VecVariantType &var, std::unordered_map<VecVariantType, int, Hasher> &m)
{
std::cout << "Lookup ";
auto it = m.find(var);
if (it != m.end())
{
std::cout << "success - " << *it << "\n";
}
else
{
std::cout << "failure\n";
}
}
int main()
{
std::unordered_map<VecVariantType, int, Hasher> m;
auto one = VecVariantType { 1, "one", 1u };
auto two = VecVariantType { 2, "two", 2u };
auto three = VecVariantType { 3, "three", 3u };
auto nnn = VecVariantType { 1, "one", 1u, 2, "two", 2u, 3, "three", 3u };
m.emplace(one, 1);
m.emplace(two, 2);
m.emplace(three, 3);
m.emplace(nnn, 999);
std::cout << "Enumerating:\n";
for (auto& item : m)
{
std::cout << " " << item << "\n";
}
lookup(one, m);
lookup(two, m);
lookup(three, m);
lookup(nnn, m);
}
如何使用变体向量作为 unordered_map 中的键?
例如,我想让下面的代码工作。
using VariantType = std::variant<int, std::string, unsigned int>;
using VecVariantType = std::vector<VariantType>;
std::unordered_map<VecVariantType, int, $some_hash_function$> m;
如何实施 $some_hash_function$?
我喜欢一个好主意...
除了“我想知道我是否可以编译它和 运行”示例之外,我不知道您如何或为什么将这样的东西用于其他东西。
#include <iostream>
#include <vector>
#include <unordered_map>
#include <variant>
using VariantType = std::variant<int, std::string, unsigned int>;
using VecVariantType = std::vector<VariantType>;
struct Hasher
{
size_t operator()(const VecVariantType &v) const
{
size_t hash = 0;
for (auto &val : v)
{
hash ^= std::hash<VariantType>()(val);
}
return hash;
}
};
std::ostream& operator<<(std::ostream& out, std::pair<const VecVariantType, int> &p)
{
out << "key: { ";
bool needs_comma = false;
for (auto &var : p.first)
{
if (needs_comma)
{
out << ", ";
}
if (std::holds_alternative<int>(var))
{
out << "int: " << std::get<int>(var);
needs_comma = true;
}
if (std::holds_alternative<std::string>(var))
{
out << "string: " << std::get<std::string>(var);
needs_comma = true;
}
if (std::holds_alternative<unsigned int>(var))
{
out << "uint: " << std::get<unsigned int>(var);
needs_comma = true;
}
}
out << " }, value: " << p.second;
return out;
}
void lookup(const VecVariantType &var, std::unordered_map<VecVariantType, int, Hasher> &m)
{
std::cout << "Lookup ";
auto it = m.find(var);
if (it != m.end())
{
std::cout << "success - " << *it << "\n";
}
else
{
std::cout << "failure\n";
}
}
int main()
{
std::unordered_map<VecVariantType, int, Hasher> m;
auto one = VecVariantType { 1, "one", 1u };
auto two = VecVariantType { 2, "two", 2u };
auto three = VecVariantType { 3, "three", 3u };
auto nnn = VecVariantType { 1, "one", 1u, 2, "two", 2u, 3, "three", 3u };
m.emplace(one, 1);
m.emplace(two, 2);
m.emplace(three, 3);
m.emplace(nnn, 999);
std::cout << "Enumerating:\n";
for (auto& item : m)
{
std::cout << " " << item << "\n";
}
lookup(one, m);
lookup(two, m);
lookup(three, m);
lookup(nnn, m);
}