【发布时间】:2017-03-20 05:35:51
【问题描述】:
是否可以使用基于范围的 for 循环来循环子范围?
std::vector <std::string> inputs={"1","abaaaa","abc","cda"};
for (auto &it : new_vector(inputs.begin()+1, inputs.end()))
{
// …
}
【问题讨论】:
标签: c++11 for-loop vector range
是否可以使用基于范围的 for 循环来循环子范围?
std::vector <std::string> inputs={"1","abaaaa","abc","cda"};
for (auto &it : new_vector(inputs.begin()+1, inputs.end()))
{
// …
}
【问题讨论】:
标签: c++11 for-loop vector range
你可以使用 Boost 的iterator_range:
for (auto &it : boost::make_iterator_range(inputs.begin()+1, inputs.end()))
{
cout << it << endl;
}
您也可以编写自己的包装器。
【讨论】:
不幸的是,C++ 标准库中没有这样的东西。但是,您可以像这样定义自己的包装器(至少需要 C++ 11 - 这在 2021 年应该不是问题):
template<typename Iter>
struct range
{
Iter b, e;
Iter begin() const { return b; }
Iter end() const { return e; }
};
template<typename T>
auto slice(const T& c, std::size_t from, std::size_t to = -1) -> range<decltype(c.begin())>
{
to = (to > c.size() ? c.size() : to);
return range<decltype(c.begin())>{c.begin() + from, c.begin() + to};
}
然后你就可以使用它了:
std::vector<int> items(100);
// Iterates from 4th to 49th item
for (auto x: slice(items, 4, 50))
{
}
// Iterates from 15th to the last item
for (auto x: slice(items, 15))
{
}
【讨论】:
长话短说,你 #include <range/v3/view/subrange.hpp> 并将你的 new_vector 更改为 ranges::subrange。就是这样。 Demo on Compiler Explorer.
鉴于您为此函数设想的名称new_vector,也许您认为您需要: 右侧的实体成为std::vector或者至少是某种容器。
如果是这种情况,那就改变主意,没有必要。 : 想要从它的“右手边”得到的只是它定义了begin 和end,无论是成员还是非成员。例如,它编译并运行得很好:
struct A {};
int* begin(A);
int* end(A);
struct B {
int* begin();
int* end();
};
int main()
{
for (auto it : A{}) {}
for (auto it : B{}) {}
}
【讨论】: