Một khả năng có thể thúc đẩy của iterator_range
(Không có một trình biên dịch hỗ trợ phạm vi có trụ sở, sử dụng BOOST_FOREACH
thay vào đó tôi. 'd mong đợi dựa trên phạm vi cho công việc giống nhau, miễn là vùng chứa hoặc dải ô có phương thức bắt đầu và kết thúc.)
#include <boost/foreach.hpp>
#include <boost/range/iterator_range.hpp>
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
BOOST_FOREACH(int n, boost::make_iterator_range(v.begin(), v.begin() + v.size()/2)) {
std::cout << n << '\n';
}
}
Để thuận tiện, bạn cũng có thể thực hiện chức năng lát của riêng mình, vì vậy nó sẽ chấp nhận các chỉ mục thay vì các trình lặp. Một lần nữa, nó có thể được dựa trên boost.iterator_range, hay không:
#include <cstddef>
#include <iterator>
template <class Iterator>
class iter_pair
{
public:
typedef Iterator iterator;
typedef Iterator const_iterator; //BOOST_FOREACH appears to want this
iter_pair(iterator first, iterator last): first(first), last(last) {}
iterator begin() const { return first; }
iterator end() const { return last; }
private:
iterator first, last;
};
template <class Container>
struct iterator_type
{
typedef typename Container::iterator type;
};
template <class Container>
struct iterator_type<const Container>
{
typedef typename Container::const_iterator type;
};
template <class Container>
iter_pair<typename iterator_type<Container>::type>
slice(Container& c, size_t i_first, size_t i_last)
{
typedef typename iterator_type<Container>::type iterator;
iterator first = c.begin();
std::advance(first, i_first);
iterator last = first;
std::advance(last, i_last - i_first);
return iter_pair<iterator>(first, last);
}
template <class Container>
iter_pair<typename iterator_type<Container>::type>
slice(Container& c, size_t i_last)
{
return slice(c, 0, i_last);
}
//could probably also be overloaded for arrays
#include <cctype>
#include <string>
#include <boost/foreach.hpp>
#include <iostream>
int main()
{
std::string s("Hello world, la-la-la!");
BOOST_FOREACH(char& c, slice(s, 2, 11)) {
if (c == 'l')
c = std::toupper(c);
}
const std::string& r = s;
BOOST_FOREACH(char c, slice(r, r.size() - 1)) {
std::cout << c << " ";
}
std::cout << '\n';
}
Nói chung người ta sẽ có thể được làm việc với lặp ở nơi đầu tiên, vì vậy nó có thể không phải là hữu ích.
Nó có lẽ chỉ là dễ dàng hơn để làm 'std :: for_each (từ, để , [] (int k) {processNumber (k);}); '. Hoặc bạn sẽ phải cung cấp một cho mỗi phạm vi con tương thích trong vectơ đó. –
Vâng, tôi biết điều đó. Tôi chỉ muốn biết các giới hạn của vòng lặp for-range trong C++ so với các ngôn ngữ khác mà việc cắt lát là "dễ dàng". – Klaim
Không phải là giải pháp 'for_each' được hiển thị ở trên" dễ dàng "? – jalf