I am try to create an iterable type which receives a template argument of a specific duration type, say std::seconds
, std::hours
, etc., and I want it to receive as argument 2 values that represent time_points
of the specified duration, and be able to use such a construct in a range based for loop by increasing the current time_point
by a unit of that duration or maybe of a specified duration, something like the following:
DateRange<std::seconds> dr(now() , 50);
for(auto d : dr){
// do something at unit time
}
I have tried to implement it this way
using namespace std::chrono;
template<typename Duration , typename Clock_t = high_resolution_clock,
typename Time_type = time_point<Clock_t, typename Duration> , typename
Time_pointer = Time_type* >
class DateRange {
using Time_type_t = typename Time_type::duration;
public:
DateRange(Time_type_t start, Time_type_t end) :
m_begin(start),
m_end(end)
{
}
DateRange(Time_type_t end):
m_begin(Clock_t::now())
{
}
Time_pointer begin(){
return &m_begin;
}
Time_pointer end() {
return &m_end;
}
Time_pointer operator++(){
present +=Duration(1);
return present_point;
}
Time_type operator*(){
return present;
}
private:
Time_type m_begin;
Time_type m_end;
Time_type present;
Time_pointer present_point = &present;
Clock_t l_clock;
};
int main()
{
DateRange<seconds> dr(40s);
dr.operator++();
std::cout << (*dr).time_since_epoch().count();
}
'std::chrono::time_point::time_point(std::chrono::time_point &&)': cannot convert argument 1 from 'std::chrono::steady_clock::time_point' to 'const _Duration &' DateRange at line 19
Range-based for loops (for ( range_declaration : range_expression ) loop_statement
) are syntactic sugar for (in your case) this:
{
auto && __range = range_expression ;
auto __begin = __range.begin();
auto __end = __range.end();
for ( ; __begin != __end; ++__begin)
{
range_declaration = *__begin;
loop_statement
}
}
Without concerning ourselves with the finer details of this (or how it changed throughout C++ versions), this explains why your code currently cannot work. You are attempting to do this:
auto && __range = myDateRange;
- Ok, our range is a DateRange
. This is fine.
auto __begin = __range.begin();
auto __end = __range.end();
So __begin
and __end
are now Time_type*
... This is already looking bad.
Now the loop will increment __begin
, but it is a TimeType*
that does not point into an array. Dereferencing the incremented __begin
(as done in the next statement) will thus be Undefined Behavior. Note how operator++
of the range_expression
is never called.
Regardless of if you fix the compiler error (and missing initialization in DateRange(Time_type_t end)
), this approach will not work. You need an iterator class that keeps a reference to your DateRange
. This iterator is returned by begin()
and end()
and has itself an operator++()
and operator*()
(which would return an appropriate time_point
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With