Чем я занимаюсь
Я практикую C ++ через 3 года. Мне нужно было учиться быстро и широко, поэтому этот пример, который я пытаюсь решить, может показаться вам странным.
Я использую c++20
, gcc 10.2
.
Я хотел сделать функцию перечисления Python, которая
- Принимает любые
container<T>
- Урожайность
std::tuple<int, T>
- Где
T
- это тип элементов в контейнере
Я хотел попробовать применить питонический диапазон в качестве аргумента enumerate
, который
- Принимает
(int start, int end, int step)
- Урожайность
int i
сstart
доend
каждыеstep
диапазон (это не мой код, я только добавил step
функции)
template <typename T>
class range_iterator;
template <typename T>
class range_impl
{
const T start_;
const T stop_;
const T step_;
public:
range_impl(T start, T stop, T step) : start_{start}, stop_{stop}, step_{step} {};
range_impl(T start, T stop) : start_{start}, stop_{stop}, step_{1} {};
range_impl(T stop) : start_{0}, stop_{stop}, step_{1} {};
range_iterator<T> begin() const
{
return range_iterator<T>{start_, step_};
}
range_iterator<T> end() const
{
return range_iterator<T>{stop_, step_};
}
};
template <typename T>
class range_iterator
{
T current_;
const T step_;
public:
range_iterator(T init, T step) : current_{init}, step_{step} {};
range_iterator<T> &operator++()
{
current_ += step_;
return *this;
}
bool operator!=(const range_iterator<T> &rhs) const
{
return current_ != rhs.current_;
}
T operator*() const
{
return current_;
}
};
template <typename T>
range_impl<T> range(const T start, const T stop, const T step)
{
return range_impl<T>(start, stop, step);
}
template <typename T>
range_impl<T> range(const T start, const T stop)
{
return range_impl<T>(start, stop);
}
template <typename T>
range_impl<T> range(const T stop)
{
return range_impl<T>(stop);
}
Может использоваться следующим образом
#include <iostream>
int main()
{
for(auto i: range(0, 100 2)
{
std::cout << i << std::endl;
}
}
Код проблемы: перечислить
template <typename T>
class enumerate_iterator;
// Here, T should be a type of a container that contains type X
template <typename T>
class enumerate_impl
{
T impl;
public:
enumerate_impl<T>(T impl) : impl{impl} {/* empty */};
enumerate_iterator begin() const
{
return enumerate_iterator{impl.begin()};
}
enumerate_iterator end() const
{
return enumerate_iterator{impl.end()};
}
};
// Here, T should be a type of a iterator, I think. Confused myself.
template <typename T>
class enumerate_iterator
{
T iterator;
int i;
public:
enumerate_iterator(T iterator) : iterator{iterator}, i{0} {/* empty body */};
enumerate_iterator<T> &operator++()
{
i++;
iterator++;
return *this;
}
bool operator!=(const enumerate_iterator<T> &rhs) const
{
return iterator != rhs.iterator;
}
std::tuple operator*() const
{
return {i, *iterator};
}
};
template <typename T>
enumerate_impl<T> enumerate(T impl)
{
return enumerate_impl<T>{impl};
}
Ожидаемое использование
#include <iostream>
int main()
{
for (auto &[i, j] : enumerate(range(0, 100, 2)))
{
std::cout << i << " " << j << std::endl;
}
}
Полученная ошибка (на самом деле ошибок компиляции очень много, но я хочу попробовать больше с другими).
utility.cpp:186:20: error: deduced class type 'tuple' in function return type
186 | std::tuple operator*() const
Я догадался, что это жалуется you didn't tell me what type the tuple contains
. Но дело в том, что я не знаю, какой тип T iterator
содержит. Как я могу сказать return type is std::tuple<int, type T contains>
?
Спасибо, что прочитали этот длинный длинный вопрос.