Jedną z możliwości może być impuls na iterator_range
(nie ma kompilatora, który obsługuje zakres oparte na, używając BOOST_FOREACH
zamiast ja. "oczekuje się, że zakres pracy będzie taki sam, o ile pojemnik lub zakres ma metodę początkową i końcową.)
#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';
}
}
Dla wygody można również utworzyć własną funkcję przekroju, aby przyjmowała indeksy zamiast iteratorów. Znowu, może to być oparte na boost.iterator_range, czy nie:
#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';
}
Ogólnie jeden prawdopodobnie pracować z iteratorów w pierwszej kolejności, więc to nie może być tak, że użyteczne.
To prawdopodobnie tylko będzie łatwiej zrobić 'std :: for_each (od, do , [] (int k) {processNumber (k);}); '. Lub musiałbyś podać dla każdego zgodnego podzakresu w tym wektorze. –
Tak, jestem tego świadomy. Po prostu chcę poznać limity pętli for-range w C++ w porównaniu do innych języków, w których cięcie jest "łatwe". – Klaim
Czy powyższe rozwiązanie "for_each" nie jest "łatwe"? – jalf