c++clockidiomsc++-chrono

Is it "legitimate" to define an std::chrono Clock which doesn't really offer a now() function?


I'm writing a C++ library, which works with data that has some time values in it - values that do not originate in the system the library runs on. I want to put such values in std::chrono::time_point's (which will be exposed to users of the library).

Now, to do that, I need to specify a Clock type. Ok, that shouldn't be a problem, right? I can meet all the requirements of , can't I? ... hmm, no, not really, I have one obstacle: The now() function. I can't provide a now() value for the system where the time point values I'm looking at were generated! I don't have access to it, and maybe it no longer even exists; and it might have just stopped, or been reset, or ceased to exist altogether.

Does that mean I should not use std::chrono types? Or should I create a clock type whose now() function returns a fixed dummy value? Or artificially-increasing value?


Solution

  • The C++20 version of <chrono> contains a clock that does not have a now() function, and indeed, has absolutely nothing in it:

    struct local_t {};
    
    template<class Duration>
        using local_time  = time_point<local_t, Duration>;
    using local_seconds = local_time<seconds>;
    using local_days    = local_time<days>;
    

    local_t is a clock, sort of. It is used to define the family of time_points called local_time. A local time does not refer to a specific instance in time until paired with a time_zone.

    local_t does not meet the Cpp17Clock requirements. However there is no requirement in the template

    template<class Clock, class Duration>
      class time_point;
    

    that Clock meet the Cpp17Clock requirements. Otherwise local_t could not exist.

    So what happens when you try to say:

    local_time<seconds>::clock::now();
    

    ?

    You get a compile-time error. This means that you can not use local_time in a call to sleep_until for example, because sleep_until requires the time_point's clock to meet the Cpp17Clock requirements.

    This relaxation of clock requirements for time_point was not standardized until C++20, expressly for the purpose of introducing local_time. However the more restricted requirements for time_point were also never enforced prior to C++20. So from a practical standpoint, you're good with taking advantage of these relaxed requirements prior to C++20.