简体   繁体   English

是否可以将基于范围的 for 循环与迭代器范围一起使用?

[英]Is it possible to use range-based for loops with iterator ranges?

Consider the usage with std::multimap , where I am given a range of iterators:考虑std::multimap的用法,在那里我得到了一系列迭代器:

std::unordered_multimap<std::string, MyObject> mymap;

auto& range = mymap.equal_range("some_key");
for (auto& the_pair : range)
{
}

Now, the code above does not compile, but I am using it for demonstration purposes.现在,上面的代码无法编译,但我将其用于演示目的。 Is it possible to use range-based for loops with a pair of iterators like this?是否可以将基于范围的 for 循环与这样的一对迭代器一起使用? I don't imagine it is possible directly, so I guess my question is really about whether or not there is an adapter class in STL for this use case.我不认为这是直接可能的,所以我想我的问题实际上是关于这个用例的 STL 中是否有适配器类。 I could probably write my own but this seems like a common case.我可能可以自己写,但这似乎是一个常见的情况。

Update:更新:

If this is not a common case and STL does not provide such a proxy or adapter for this type of usage, what is required to implement them?如果这不是一个常见的情况并且 STL 没有为这种类型的使用提供这样的代理或适配器,那么实现它们需要什么? I was thinking that I'd need to overload the free functions begin and end and also define an adapter iterator class for std::pair<T,U> .我在想我需要重载自由函数beginend并为std::pair<T,U>定义一个适配器迭代器类。 I'm just taking a conceptual stab at it, but please let me know!我只是在概念上尝试一下,但请告诉我! Thanks in advance everyone.提前谢谢大家。

No, range-based for calls std::begin and std::end .不,基于范围的调用std::beginstd::end There isn't any overloads for std::pair . std::pair没有任何重载。 At one point, this feature existed in a draft standard but was removed.曾几何时,此功能存在于标准草案中,但已被删除。 You can write your own code.您可以编写自己的代码。 Stealing from sellibitze:从sellibitze窃取:

template<class Iter>
struct iter_pair_range : std::pair<Iter,Iter> {
    iter_pair_range(std::pair<Iter,Iter> const& x)
    : std::pair<Iter,Iter>(x)
    {}
    Iter begin() const {return this->first;}
    Iter end()   const {return this->second;}
};

template<class Iter>
inline iter_pair_range<Iter> as_range(std::pair<Iter,Iter> const& x)
{ return iter_pair_range<Iter>(x); }

int main() {
    std::unordered_multimap<std::string, MyObject> mymap;

    auto range = mymap.equal_range("some_key");
    for (auto& the_pair : as_range(range))
    {
    }
}

You can look at n2995 from 2009 which talks about adding ranged support to the standard library.您可以查看 2009 年的n2995 ,它讨论了向标准库添加范围支持。 Maybe you're better off using Boost.Range .也许你最好使用Boost.Range

The template-based answer is probably what you are looking for, but i would use a for_each instead with a lambda.基于模板的答案可能正是您要寻找的,但我会使用for_each代替 lambda。 It is cleaner and easier to digest.它更清洁,更容易消化。

With C++ 20 you can use std::ranges::subrange .使用 C++ 20,您可以使用std::ranges::subrange

std::unordered_multimap<std::string, MyObject> mymap;

auto range = mymap.equal_range("some_key");
for (auto & [key, value] : std::ranges::subrange(range.first, range.second))
{
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM