<< (now - 7_days) << '\n';
}
8. Компиляция и запуск программы дадут следующий результат. Поскольку мы использовали в качестве строки форматирования %c
$ ./relative_absolute_times
The current date and time is Fri May 5 13:20:38 2017
In 12 hours, it will be Sat May 6 01:20:38 2017
12 hours and 15 minutes ago, it was Fri May 5 01:05:38 2017
1 week ago, it was Fri Apr 28 13:20:38 2017
Как это работает
Мы получили текущий момент времени из std::chrono::system_clock
time
, которая может быть отображена в виде понятной человеку строки описания.Чтобы вывести на экран такие моменты времени, мы реализовали оператор <<
ostream& operator<<(ostream &os,
const chrono::time_point
{
const auto tt (chrono::system_clock::to_time_t(t));
const auto loct (std::localtime(&tt));
return os << put_time(loct, "%c");
}
Здесь мы сначала преобразуем экземпляр типа chrono::time_point
std::time_t
. Значения этого типа можно преобразовать в локальное время, что мы делаем с помощью функции std::localtime
. Она возвращает указатель на преобразованное значение (не волнуйтесь об управлении памятью, лежащей за данным указателем; это статический объект, и для него память в куче не выделяется), которое мы наконец можем вывести на экран.Функция std::put_time
"%c"
отображает стандартную строку даты-времени, например "Sun Mar 12 11:33:40 2017"
.Мы также могли бы указать строку "%m/%d/%y"
Помимо вывода на экран мы добавили смещения к нашему моменту времени. Это было просто, поскольку можно выразить промежутки времени, такие как
12h+15min
. Пространство имен chrono_literals
предоставляет удобные литералы типов для часов (h
), минут (min
), секунд (s
), миллисекунд (ms
), микросекунд (us
) и наносекунд (ns
).Добавление подобной продолжительности к значению момента времени создает новое значение момента времени, поскольку типы имеют соответствующие перегруженные версии операторов +
–
, именно поэтому так легко добавлять и отображать смещения времени.Безопасно извещаем о сбое с помощью std::optional
Когда программа общается с внешним миром и полагается на значения, получаемые извне, могут происходить всевозможные сбои.
Это означает вот что: когда мы пишем функцию, которая должна возвращать значение, но также может дать сбой, это нужно отразить с помощью неких изменений в интерфейсе функции. У нас есть несколько вариантов. Посмотрим, как разработать интерфейс функции, которая возвращает строку, но способна дать сбой:
□ использовать возвращаемое значение, указывающее на успех, и выходные параметры: bool get_string(string&);
□ возвращать указатель (или умный указатель), значение которого можно установить на nullptr
string* get_string();
;□ генерировать исключение в случае сбоя и оставить сигнатуру функции очень простой: string get_string();
Все эти подходы имеют свои преимущества и недостатки. Начиная с C++17, существует новый тип, который можно применять для решения такой задачи другим способом: std::optional
Мы можем обернуть в тип optional
Как это делается
В этом примере мы реализуем программу, которая считывает целые числа, поступающие от пользователя, и складывает их. Поскольку пользователь всегда может ввести случайные символы вместо чисел, мы увидим, как тип optional
1. Сначала включим все необходимые заголовочные файлы и объявим об использовании пространства имен std
#include
#include