C++ std::multimap获得两个范围

C++ std::multimap获得两个范围,c++,iterator,range,std,multimap,C++,Iterator,Range,Std,Multimap,我使用C++ STD::MultMAPP,我必须循环两个不同的键。除了创建两个范围并分别在这些范围上循环外,还有其他有效的方法吗 我现在就是这样做的: std::pair<std::multimap<String, Object*>::iterator,std::multimap<String, Object*>::iterator> range; std::pair<std::multimap<String, Object*>::iter

我使用C++ <代码> STD::MultMAPP,我必须循环两个不同的键。除了创建两个范围并分别在这些范围上循环外,还有其他有效的方法吗

我现在就是这样做的:

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)
{
    ...
}
std::对范围;
std::配对范围2;
//获取字符串键的范围
范围=多重映射。相等范围(键1);
range2=多重映射。相等_范围(键2);
for(std::multimap::iterator it=range.first;it!=range.second;++it)
{
...
}
对于(std::multimap::迭代器it2=range2.first;it2!=range2.second;++it2)
{
...
}

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

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

编辑:我想得太多了;将两个循环修改为一个循环很容易

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;
    }
    ...
}
for(std::multimap::iterator it=range.first;it!=range2.second;++it)
{
if(it==range.second)
{
它=范围2.1;
if(it==范围2.秒)
打破
}
...
}

当然,Boost可以做到这一点。使用Boost.Range及其
join
函数将得到您想要的。有关更多详细信息,请参阅。

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

// 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)
{
    ...
}
无论如何,我只需测试键,并且仅在键2!=关键1。每次在循环中检查迭代器都会有一些代价

第一个范围与第二个范围的std::set_差异可能会简化代码。 也许std::将两个范围合并,然后通过后插入器插入到一个集合中,这样您就只能得到一个副本


一些实验可能是正确的。别忘了把你的第一个猜测放在组合中。它可能会让你感到惊讶,因为它的速度非常好。除非范围通常很长和/或循环操作很昂贵,否则可能不值得额外簿记。

为什么您认为它效率不高?这是我第一次使用multimap,所以我对它们不太熟悉。我将在这些循环中做很多工作,我想知道是否还有另外一种操作,可以同时获得两个范围或其他什么。你能举一个键重叠但彼此不相等的键的例子吗?也许我的大脑是湿漉漉的,但似乎一个简单的按键平等检查就可以了。如果每个查询都有单独的下限和上限,这对我来说更有意义。这是一个很好的例子,当单个
typedef
可以消除较大的一半代码并使代码更具可读性时:
typedef std::multimap::iterator Iter
谢谢,Boost看起来非常强大。不幸的是,我的公司是老派的,讨厌新事物。。。我想他们将不得不满足于效率低下。这一次,这不是效率问题,而是方便问题。我也想到了这一点。但是,这两个键必须相邻才能工作吗?例如,如果我有三把钥匙,我想在第一把钥匙和第三把钥匙上循环,那么第二把钥匙不也包括在内吗?或者那些if语句解决了这个问题吗?@Kaiser,
if
语句处理从第一个范围到第二个范围的转换。它们甚至可能出现故障。他们唯一做不到的就是相交;如果
range2
包含
range.second
那么你会得到一个无限循环。啊,我明白了。我的range2是静态的,range1总是不同的。它们不应该相交,对吗?由于multimap在插入时对其进行排序?@Kaiser,只要键不同,并且您像您在问题中所做的那样使用
equal_range
,这些范围就不会相交。我还检查了以确保您的
range2
迭代器不会因插入而无效: