цикл на основе диапазона C++11 для диапазона (L, R)
C++11 не имеет цикла на основе диапазона для целой последовательности.
for(auto e : {0..10} ) // wouldn't compile!!!
поэтому я просто решил имитировать его.
template< class T , bool enable = std::is_integral<T>::value >
struct range_impl
{
struct iterator
{
constexpr T operator * ()const noexcept { return value; }
iterator& operator ++()noexcept { ++value; return *this; }
friend
constexpr bool operator != (const iterator & lhs, const iterator rhs ) noexcept
{
return lhs.value != rhs.value;
}
T value;
};
constexpr iterator begin()const noexcept { return { first }; }
constexpr iterator end ()const noexcept { return { last }; }
T first;
T last ;
};
template< class T >
range_impl<T> range(T first , T last) noexcept
{
return {first, last};
}
int main(){
// print numbers in [ 0..10 ), i.e. 0 1 2 3 4 5 6 7 8 9
for(auto e : range(0,10) ) std::cout << e << ' ';
std::cout << std::endl;
}
Q: Как обобщить этот метод для ForwardIterators?
пример:
template< class ForwardIterator, class T >
bool find(ForwardIterator first, ForwardIterator last, T const& value)
{
for(auto e: range(first, last) ) if (e == v) return true;
return false;
}
2 ответов
специализация
template< class Iterator>
struct range_impl<Iterator, false>
{
range_impl(Iterator first, Iterator last)
: first(first), last(last)
{}
constexpr Iterator begin()const noexcept { return { first }; }
constexpr Iterator end ()const noexcept { return { last }; }
Iterator first;
Iterator last ;
};
тест:
int main(){
for(auto e : range(0,10) ) std::cout << e << ' ';
std::cout << std::endl;
const char* a[] = { "Say", "hello", "to", "the", "world" };
for(auto e : range(a, a + 5) ) std::cout << e << ' ';
std::cout << std::endl;
}
вы пытаетесь переопределить boost::iterator_range
и boost::counting_iterator
. Просто сделайте это вместо этого:
template< class T >
boost::iterator_range< boost::counting_iterator<T> > range( T const& tBegin, T const& tEnd ) {
return boost::iterator_range< boost::counting_iterator<T> >( tBegin, tEnd );
}
существует даже boost::counting_range
уже: http://www.boost.org/doc/libs/1_47_0/libs/range/doc/html/range/reference/ranges/counting_range.html