std :: multimap获得两个范围

时间:2011-09-07 15:16:41

标签: c++ iterator range std multimap

我正在使用C ++ std::multimap,我必须遍历两个不同的键。除了创建两个范围并单独循环这些范围之外,是否有一种有效的方法可以做到这一点?

这就是我现在这样做的方式:

std::pair<std::multimap<String, Object*>::iterator,std::multimap<String, Object*>::iterator> range;
std::pair<std::multimap<String, Object*>::iterator,std::multimap<String, Object*>::iterator> range2;

// get the range of String key
range = multimap.equal_range(key1);
range2 = multimap.equal_range(key2);

for (std::multimap<String, Object*>::iterator it = range.first; it != range.second; ++it)
{
    ...
}
for (std::multimap<String, Object*>::iterator it2 = range2.first; it2 != range2.second; ++it2)
{
    ...
}

3 个答案:

答案 0 :(得分:3)

您开始使用的代码是最简单的。

如果你真的想在同一个循环中迭代两个范围,你可以创建一个自定义迭代器,它接受两个迭代器范围,迭代第一个直到它完成然后切换到第二个。这可能比它的价值更麻烦,因为你需要自己实现所有的迭代器成员。

编辑:我在思考这个问题;只需将两个循环修改为一个循环就很容易。

for (std::multimap<String, Object*>::iterator it = range.first; it != range2.second; ++it)
{
    if (it == range.second)
    {
        it = range2.first;
        if (it == range2.second)
            break;
    }
    ...
}

答案 1 :(得分:3)

当然,Boost会这样做。使用Boost.Range及其join函数可以获得您想要的效果。有关详细信息,请参阅Boost Range Library: Traversing Two Ranges Sequentially

答案 2 :(得分:0)

如果您可以访问C ++ - 11(Visual Studio 10 +,gcc-4.5 +)并且允许使用它auto是一个真正的宝石:

// get the range of String key
auto range = multimap.equal_range(key1);
auto range2 = multimap.equal_range(key2);

for (auto it = range.first; it != range.second; ++it)
{
    ...
}
for (auto it2 = range2.first; it2 != range2.second; ++it2)
{
    ...
}

无论如何,我只是测试键,只有key2!= key1才进行第二次循环。每次循环检查迭代器都会产生一些成本。

第二个范围的std :: set_difference可能会简化代码。 也许std :: set_union这两个范围并通过back_inserter插入到一个集合中,这样你只得到一个副本?

可能需要进行一些实验。别忘了把你的第一个猜测放在混合中。在速度方面,它可能会让你感到惊讶。除非范围通常很长和/或循环操作很昂贵,否则可能不值得额外记账。