Я хотел бы иметь собственный цикл на основе диапазона, но без конструктора копирования. Кажется, в какой-то момент есть копия, но я не понимаю, почему.
Вот пример, который я хотел бы запустить: http://cpp.sh/63pa6
class Range
{
public:
Range( int begin, int end )
: iter_( begin ),
last_( end )
{
}
Range(Range&&) = default;
Range& operator=(Range&&) = default;
Range(const Range&) = delete;
bool operator!=( const Range & /*unused*/ ) const
{
return iter_ != last_;
}
void operator++()
{
++iter_;
}
const Range &begin() const
{
return *this;
}
const Range &end() const
{
return *this;
}
int operator*() const
{
return iter_;
}
private:
int iter_;
int last_;
};
Этот код не компилируется:
int main()
{
for( auto i : Range( 2, 8 ) )
{
std::cout << i << std::endl;
}
}
Ошибка компиляции: error: use of deleted function 'Range::Range(const Range&)'
Я считаю, что конечный итератор всегда копируется в цикле for на основе диапазона. Вместо этого ваш конечный итератор должен быть дозорным объектом.





Диапазон для цикла производит следующий код:
{
auto && __range = range_expression ;
for (auto __begin = begin_expr, __end = end_expr;
__begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
}
Как видите, это создает две копии, __begin и __end.
Я думаю, что это проще, когда вы определяете оболочку итератора:
struct range : std::pair<int,int> {
struct int_iter {
int_iter( int i ) : i(i) {}
int operator*() { return i; }
int &operator++() { return ++i; }
bool operator!=( int_iter end ) const { return i != end.i; }
private:
int i;
};
using std::pair<int,int>::pair;
int_iter begin() const { return int_iter( first ); }
int_iter end() const { return int_iter(second); }
};
Пожалуйста, добавьте минимальный воспроизводимый пример.