是否可以将基于范围的 for 循环与迭代器范围一起使用?
Is it possible to use range-based for loops with iterator ranges?
考虑 std::multimap
的用法,我得到了一系列迭代器:
std::unordered_multimap<std::string, MyObject> mymap;
auto& range = mymap.equal_range("some_key");
for (auto& the_pair : range)
{
}
现在,上面的代码无法编译,但我将其用于演示目的。是否可以像这样将基于范围的 for 循环与一对迭代器一起使用?我认为这不可能直接实现,所以我想我的问题实际上是关于此用例的 STL 中是否有适配器 class。我可能会自己写一个,但这似乎很常见。
更新:
如果这不是常见情况并且 STL 不为此类用法提供此类代理或适配器,那么需要什么来实现它们?我在想我需要重载自由函数 begin
和 end
并为 std::pair<T,U>
定义适配器迭代器 class。我只是对其进行概念性的尝试,但请告诉我!提前谢谢大家。
否,基于范围的调用 std::begin
和 std::end
。 std::pair
没有任何重载。有一次,这个 feature existed in a draft standard 但被删除了。您可以编写自己的代码。从 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))
{
}
}
你可以看看n2995 from 2009 which talks about adding ranged support to the standard library. Maybe you're better off using Boost.Range.
基于模板的答案可能是您正在寻找的答案,但我会使用 for_each 而不是 lambda。它更干净,更容易消化。
对于 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))
{
}
考虑 std::multimap
的用法,我得到了一系列迭代器:
std::unordered_multimap<std::string, MyObject> mymap;
auto& range = mymap.equal_range("some_key");
for (auto& the_pair : range)
{
}
现在,上面的代码无法编译,但我将其用于演示目的。是否可以像这样将基于范围的 for 循环与一对迭代器一起使用?我认为这不可能直接实现,所以我想我的问题实际上是关于此用例的 STL 中是否有适配器 class。我可能会自己写一个,但这似乎很常见。
更新:
如果这不是常见情况并且 STL 不为此类用法提供此类代理或适配器,那么需要什么来实现它们?我在想我需要重载自由函数 begin
和 end
并为 std::pair<T,U>
定义适配器迭代器 class。我只是对其进行概念性的尝试,但请告诉我!提前谢谢大家。
否,基于范围的调用 std::begin
和 std::end
。 std::pair
没有任何重载。有一次,这个 feature existed in a draft standard 但被删除了。您可以编写自己的代码。从 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))
{
}
}
你可以看看n2995 from 2009 which talks about adding ranged support to the standard library. Maybe you're better off using Boost.Range.
基于模板的答案可能是您正在寻找的答案,但我会使用 for_each 而不是 lambda。它更干净,更容易消化。
对于 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))
{
}