c++ - 结构键和 getter 函数的哈希映射
问题描述
我有一个嵌套结构(简化):
struct Person {
struct JobDetails {
std::string company_name;
std::string address;
};
JobDetails job_details;
int32_t age;
std::string name;
};
是否可以为每个结构字段创建键和 getter(函数)的哈希映射,即使是嵌套字段?
例如
std::unordered_map<std::string, ???> hash_map{
"company_name", [](Person const& person) { return person.job_details.company_name; },
"age", [](Person const& person) { return person.age }
};
auto value = hash_map["company_name"](person);
解决方案
有些。您希望std::function<something>
作为地图的值类型能够存储各种 lambda。更难的问题是每个表达式都必须具有在编译时已知的单一类型。如果我有 a std::string key;
,那么表达式hash_map[key](person)
可以是 astd::string
或 an int32_t
,或者可能是其他类型。
也许您可以使用字符串属性函数的映射、数字属性函数的不同映射以及更多(如果需要)。
或者,如果您真的想要一个存储多种值类型的映射,astd::variant
可能会有所帮助。
using PersonProperty = std::variant<std::string, std::int32_t>; // more?
using PersonPropertyGetter = std::function<PersonProperty(Person const&)>;
std::unordered_map<std::string, PersonPropertyGetter> hash_map{
{ "company_name", [](Person const& person) { return person.job_details.company_name; } },
{ "age", [](Person const& person) { return person.age } }
};
然后你需要使用std::visit
orstd::get
或std::get_if
来实际使用std::variant
.
std::visit([&prop_name](auto const& value)
{ std::cout << prop_name << ": " << value; },
hash_map[prop_name]);
std::visit(overloaded{
[](std::string const&) { std::cout << " (string)\n"; },
[](int32_t) { std::cout << " (int32_t)\n"; } });
auto prop_value = hash_map[prop_name];
if (std::string const* str_value = std::get_if<std::string>(prop_value))
do_a_string_thing(*str_value);
int32_t age = std::get<int32_t>(hash_map["age"](person)); // Throws if wrong type!
一个示例中使用的overloaded
工具在 cppreference 页面的示例中定义std::visit
。只需放入一个方便的头文件:
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
推荐阅读
- java - 如何根据打开的拨动开关更改多个主题
- c# - 使用连接字符串 localhost\SQLEXPRESS 的用户 C# 登录失败
- inheritance - 首先在实体框架代码中转换为派生类型
- vba - 如何将一系列单元格转换为文本?
- web-services - 在后台运行 golang 网络服务器
- python - 调用sync_reasoner时Owlready2解析错误
- android - 如何在 Delphi Android 中为 TComboEdit 输入 TextPrompt 字段
- security - 什么 OCRASuite 值在 OATH 挑战-响应算法中使用“Protectimus”?
- javascript - CSS覆盖关闭按钮滚动到页面顶部
- sql - 当前的 NLP 到 SQL 查询解决方案