I have a piece of code where std::chrono::duration<int64_t, std::milli>
is subclassed, and used to create a std::chrono::time_point
, like so:
#include <chrono>
class my_duration : public std::chrono::duration<int64_t, std::milli>
{ /* snip */ };
int main()
{
typedef std::chrono::time_point< std::chrono::system_clock, my_duration > my_time_point;
my_time_point t( my_duration{} );
//....
}
This was seemingly compiling and working fine when using GCC < 10. However, when using GCC 10, a static assertion in std::chrono::time_point will fail with:
/opt/wandbox/gcc-head/include/c++/11.0.0/chrono:764:37: error: static assertion failed: duration must be a specialization of std::chrono::duration
This can be seen at the following link, which also demonstrates that clang gives the same error: https://wandbox.org/permlink/CQw6fWt4kZ1xYdet
In std::chrono, the failing assert is due to the __is_duration
structs used by time_point
:
template<typename _Tp>
struct __is_duration
: std::false_type
{ };
template<typename _Rep, typename _Period>
struct __is_duration<duration<_Rep, _Period>>
: std::true_type
{ };
//... further down, in time_point:
static_assert(__is_duration<_Dur>::value,
"duration must be a specialization of std::chrono::duration");
My understanding of it is that __is_duration<my_duration>
will be an std::false_type
causing the static assert to fail.
So, my question is: does this mean it isn't possible to subclass std::chrono::duration and use the derived class with time_point? Or is there some trick that will allow the duration subclass to pass the static assertion?
std::time_point
has always required that the duration type be a specialization of std::duration
. If it isn't, then the program is ill-formed (aka: compile error). This may just be the first time GCC implemented that requirement.
Deriving from duration
doesn't really serve any useful purpose.