Monday, 3 June 2024

Learn C++ by Example: chapter 4

I started to share some details about my latest book "Learn C++ by Example", and gave an overview of the chapter three last time last time.



You can buy my book directly here: http://mng.bz/AdAQ - or just go look at the table of contents. You can also buy it from Amazon: https://amzn.to/4dMJ0aG

Chapter 4 explores time points and durations and introduces literal suffixes. As with previous chapters, several other useful C++ features crop up too. We start by finding out the current date and time:

std::chrono::time_point now = std::chrono::system_clock::now();

This uses the chrono library introduced in C++11, and later in the chapter we use the calendrical types introduced in C++20. If you haven't met either of these features before, they feel very different to, say, using C's time_t. The chapter shows how to write countdowns to various dates, for example the end of a specific year or the end of the current year. 

For example, we can hard code a specific date, using C++20's year, month day, and transform it to time_point using sys_days:

auto new_years_eve = std::chrono::year_month_day(
    std::chrono::year(2022),
    std::chrono::month(12),
    std::chrono::day(31)
);
auto event = std::chrono::sys_days(new_years_eve);

If we subtract the current time, we obtain a duration:

std::chrono::duration dur = event - now;

That gives us our first countdown, but there are details behind the times, dates and durations. If we print out the duration, the result varies between compilers. Visual Studio 2022 gave

69579189669221[1/10000000]s

while clang and gcc both gives the result in "ns". This gives us a hint that durations are in units.

We can change hours to milliseconds with an implicit cast:

std::chrono::milliseconds ms = std::chrono::hours(2);

but going back to hours from a more fine grained duration requires an explicit cast:

auto two_hours_from_ms = duration_cast<hours>(ms);

The library tends to give compile errors if you get something wrong, which is a good thing. 

In order to fully understand how the duration casts work, we need to delve into std::ratio, which is used to define seconds, minutes and so on.

The chapter gives a brief introduction to requirements and concepts too, which is a big topic. At a high level, they provide constraints for template arguments, picking appropriate overloads or giving clearer compiler error messages. 

The chapter also covers literal suffixes, such as "Hello, world!"s to make a std::string rather than a char *. Chrono also provides operator""s, taking a number, so we can write 59s for 59 seconds. We could say seconds{59} instead, but in conjunction with the overloaded operator /, we can write dates clearly in code. For example, 

auto new_years_eve = 2022y / December / 31;

is hopefully obvious, even if you don't know C++ or the how the chrono library works.


So, some questions/challenges for you. 
  • Try to write various dates and times and find the durations between them.
  • How many seconds are there in a year? (Yes, a bit of a trick question!)
  • Write your own duration and corresponding literal operator. 


No comments:

Post a Comment