检查地图中的'最深'元素

时间:2013-06-20 08:09:40

标签: c++ map stl

我有map<int, map<int, int>>

第一个键代表节点,第二个键代表属性,“最深”元素代表特定值。

我需要检查那个元素,但是执行以下操作不必要为我的地图添加键:

map<int, map<int, int>> test;
if (test[4][3] > 5)
{
    //do something
}

我想到的替代方案是

map<int, map<int, int>> test;
if (test.find(4) != test.end())
{
    if (test[4].find(3) != test[4].end())
    {
        if (test[4][3] > 5)
        {
            //do something
        }
    }
}

有更好的方法吗?我不知道地图中是否存在密钥[4][3],我不想不必要地添加它。谢谢!

3 个答案:

答案 0 :(得分:3)

这应该工作 - 首先你在第一个地图中搜索并保存返回的迭代器,然后如果该迭代器有效你搜索他指向的地图并将结果保存在另一个迭代器中,如果他有效则意味着您寻求的对象存在,您只需检查它的值:

map<int, map<int, int>> test;
map<int, map<int, int>>::iterator it1;
map<int, int>::iterator it2;
if ((it1 = test.find(4)) != test.end())
{
    if ((it2 = it1->second.find(3)) != it1->second.end())
    {
        if (it2->second > 5)
        {
            //do something
        }
    }
}
return 0;

答案 1 :(得分:1)

与Tomer Arazy的建议没有根本的区别,但是利用C ++ 11的decltype来摆脱重复的类型声明(纠正在修改地图的数据类型时可能会很乏味):

#include <map>
#include <iostream>

int main()
{
  using std::map;

  map<int, map<int, int>> test;
  test[4][3] = 6;

  decltype(test.begin())                 outer;
  decltype(test.begin()->second.begin()) inner;

  if (((outer = test.find(4)) != test.end())
      && ((inner = outer->second.find(3)) != outer->second.end())
      && (inner->second > 5))
    std::cout << "Found!" << std::endl;

  return 0;
}

(请注意,decltype()的参数未被评估,因此即使地图为空也是如此。)

这显然只适用于C ++ 11。


在C ++ 11的上下文中要提到的另一件事是,std::map现在具有类似于at()的{​​{1}}函数。它返回给定键的值,如果该键不存在则抛出异常。如果您将密钥不存在作为错误条件,这只是一个有用的想法。但如果是这样,你可以使用

std::vector

然后可能会在某处捕获if (test.at(4).at(3) > 5) std::cout << "Found!" << std::endl; 异常。

答案 2 :(得分:0)

我认为这可能会让您更容易看到发生了什么:

map<int, map<int, int>> test; 
map<int, map<int, int>>::iterator outer = test.find(4);
if (outer != test.end())
{
    map<int, int>::iterator inner = outer->second.find(3);
    if (inner != outer->second.end())
    {
        if (inner->second > 5)
        {
            //do something
        }
    }
}
return 0;