嵌套 std::map 的单行查找
Single line lookup for nested std::map
假设我有一个 std::map<int, std::map<int, std::string>>
,如果在较短的语句中给定两个键,是否可以直接查找字符串?
一些语法糖:
std::map<int, std::map<int, std::string>> nested_map;
nested_map[1][3] = "toto";
int key1 = 1;
int key2 = 3;
std::string val;
auto it1 = nested_map.find(key1);
if (it1 != nested_map.end())
{
auto it2 = it1->second.find(key2);
if (it2 != it1->second.end())
{
val = it2->second;
}
}
编辑:我只是在寻找语法糖来节省一点输入,因为我的代码中有很多这样的嵌套映射。
Edit2:我不想失败。
编写一个递归可变参数模板函数,该函数接受按引用映射和键作为可变参数模板参数,以及最内层值类型的 returnstd::optional
。或者可能 return 带有 nullptr
指示未找到的指针。
像这样的简单(可能是内联的)函数怎么样:
using nested_map = std::map<int, std::map<int, std::string>>;
bool find_value(const nested_map& map, int key1, int key2, std::string& val)
{
auto it1 = nested_map.find(key1);
if(it1 == map.end()) return false;
auto it2 = it1->second.find(key2);
if(it2 == it1->second.end()) return false;
val = it2->second;
return true;
}
std::string val;
if(find_value(map, 1, 3, val))
{
// do something useful
}
替代版本,更短,但在内部使用异常:
bool find_value(const nested_map& map, int key1, int key2, std::string& val)
{
try { val = map.at(key1).at(key2); }
catch(...) { return false; }
return true;
}
创建函数来缩短代码(并消除重复)并没有错。
这是我的看法
#include <iostream>
#include <map>
#include <string>
using nested_map_t = std::map<int, std::map<int, std::string>>;
// helper struct, to be able to return 2 values from lookup function
struct lookup_t
{
bool success = false; // lookup was successful then this will become true
std::string value; // the lookup value (empty string by default)
// implicit cast to bool, so we can use the return value in an if statement
operator bool() const
{
return success;
}
};
auto lookup_in(const nested_map_t& map, int key1, int key2)
{
lookup_t result;
auto it1 = map.find(key1);
if (it1 != map.end())
{
auto it2 = it1->second.find(key2);
if (it2 != it1->second.end())
{
result.value = it2->second;
result.success = true;
}
}
return result;
}
int main()
{
nested_map_t nested_map;
nested_map[1][3] = "toto";
// syntactic sugar : bool cast of result
if (auto result = lookup_in(nested_map, 1, 3))
{
std::cout << result.value << "\n";
}
}
关于“我不想失败”。是完全没有异常还是捕获异常可以?
#include <map>
#include <string>
#include <iostream>
#include <exception>
std::string Get_Value(const std::map<int, std::map<int, std::string>> &in, int key1, int key2) {
std::string res;
try {
res = in.at(key1).at(key2);
}
catch (const std::out_of_range &err) {
res = std::string();
}
return res;
}
int main(int argc, char * argv[]) {
std::map<int, std::map<int, std::string>> nested_map;
nested_map[1][3] = "toto";
nested_map[1][2] = "tinman";
nested_map[2][1] = "africa";
auto res = Get_Value(nested_map, 1, 3);
std::cout << res << std::endl;
res = Get_Value(nested_map, 2, 1);
std::cout << res << std::endl;
res = Get_Value(nested_map, 1, 1);
std::cout << res << std::endl;
return 0;
}
如果您不关心为无效键插入空字符串,这将 return 新添加的字符串:
std::map<int, std::map<int, std::string>> nested_map;
nested_map[1][3] = "toto";
std::string val = nested_map[2][4];
假设我有一个 std::map<int, std::map<int, std::string>>
,如果在较短的语句中给定两个键,是否可以直接查找字符串?
一些语法糖:
std::map<int, std::map<int, std::string>> nested_map;
nested_map[1][3] = "toto";
int key1 = 1;
int key2 = 3;
std::string val;
auto it1 = nested_map.find(key1);
if (it1 != nested_map.end())
{
auto it2 = it1->second.find(key2);
if (it2 != it1->second.end())
{
val = it2->second;
}
}
编辑:我只是在寻找语法糖来节省一点输入,因为我的代码中有很多这样的嵌套映射。
Edit2:我不想失败。
编写一个递归可变参数模板函数,该函数接受按引用映射和键作为可变参数模板参数,以及最内层值类型的 returnstd::optional
。或者可能 return 带有 nullptr
指示未找到的指针。
像这样的简单(可能是内联的)函数怎么样:
using nested_map = std::map<int, std::map<int, std::string>>;
bool find_value(const nested_map& map, int key1, int key2, std::string& val)
{
auto it1 = nested_map.find(key1);
if(it1 == map.end()) return false;
auto it2 = it1->second.find(key2);
if(it2 == it1->second.end()) return false;
val = it2->second;
return true;
}
std::string val;
if(find_value(map, 1, 3, val))
{
// do something useful
}
替代版本,更短,但在内部使用异常:
bool find_value(const nested_map& map, int key1, int key2, std::string& val)
{
try { val = map.at(key1).at(key2); }
catch(...) { return false; }
return true;
}
创建函数来缩短代码(并消除重复)并没有错。 这是我的看法
#include <iostream>
#include <map>
#include <string>
using nested_map_t = std::map<int, std::map<int, std::string>>;
// helper struct, to be able to return 2 values from lookup function
struct lookup_t
{
bool success = false; // lookup was successful then this will become true
std::string value; // the lookup value (empty string by default)
// implicit cast to bool, so we can use the return value in an if statement
operator bool() const
{
return success;
}
};
auto lookup_in(const nested_map_t& map, int key1, int key2)
{
lookup_t result;
auto it1 = map.find(key1);
if (it1 != map.end())
{
auto it2 = it1->second.find(key2);
if (it2 != it1->second.end())
{
result.value = it2->second;
result.success = true;
}
}
return result;
}
int main()
{
nested_map_t nested_map;
nested_map[1][3] = "toto";
// syntactic sugar : bool cast of result
if (auto result = lookup_in(nested_map, 1, 3))
{
std::cout << result.value << "\n";
}
}
关于“我不想失败”。是完全没有异常还是捕获异常可以?
#include <map>
#include <string>
#include <iostream>
#include <exception>
std::string Get_Value(const std::map<int, std::map<int, std::string>> &in, int key1, int key2) {
std::string res;
try {
res = in.at(key1).at(key2);
}
catch (const std::out_of_range &err) {
res = std::string();
}
return res;
}
int main(int argc, char * argv[]) {
std::map<int, std::map<int, std::string>> nested_map;
nested_map[1][3] = "toto";
nested_map[1][2] = "tinman";
nested_map[2][1] = "africa";
auto res = Get_Value(nested_map, 1, 3);
std::cout << res << std::endl;
res = Get_Value(nested_map, 2, 1);
std::cout << res << std::endl;
res = Get_Value(nested_map, 1, 1);
std::cout << res << std::endl;
return 0;
}
如果您不关心为无效键插入空字符串,这将 return 新添加的字符串:
std::map<int, std::map<int, std::string>> nested_map;
nested_map[1][3] = "toto";
std::string val = nested_map[2][4];