Задача простая: реализовать range-based итератор для произвольной структуры. При этом он должен быть как можно проще и содержать строго необходимые методы.
Что получилось (вектор просто для примера):
#include <vector>
#include <iostream>
class Range
{
private:
	class Impl
	{
	public:
		using value_type = int;
		using const_reference = const int&;
		Impl(const size_t v, const std::vector<int> &values) : m_idx(v), m_values(values) {}
		const_reference operator*() const { return m_values[m_idx]; }
		Impl& operator++()
		{
			m_idx++;
			return *this;
		}
		bool operator!=(const Impl& rhs) { return m_idx != rhs.m_idx; }
	private:
		// Тут может быть что угодно.
		size_t m_idx;
		const std::vector<int> &m_values;
	};
public:
	Range(const std::vector<int> &values) : m_values(values) {}
	typedef Impl iterator;
	iterator begin() const { return Impl(0, m_values); }
	iterator end() const { return Impl(m_values.size(), m_values); }
private:
	// Тут может быть что угодно.
	const std::vector<int> &m_values;
};
int main(int argc, char *argv[])
{
	const std::vector<int> values = { 1, 2, 3, 4 };
	for (const int &v : Range(values))
	{
		std::cout << v << std::endl;
	}
	return 0;
}
Вопросы:
- Что можно убрать? Что лишнее?
 - Что нужно добавить, чтобы даже самые злые линтеры не возмущались?
 
По факту, 90% кода - мусор. Всё что нужно, это своя реализация T& operator++().
То есть хотелось бы получить возможность использовать подход rust'a, где мне нужно реализовать только метод next():
struct Range<'a> {
    idx: usize,
    values: &'a Vec<i32>,
}
impl<'a> Range<'a> {
    fn new(values: &'a Vec<i32>) -> Self {
        Range {
            idx: 0,
            values,
        } 
    }
}
impl<'a> Iterator for Range<'a> {
    type Item = i32;
    
    fn next(&mut self) -> Option<Self::Item> {
        if self.idx == self.values.len() {
            return None;
        }
        
        self.idx += 1;
        Some(self.values[self.idx - 1])
    }
}
fn main() {
    let values = vec![1, 2, 3, 4];
    
    for v in Range::new(&values) {
        println!("{}", v);
    }
}




