TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.37K subscribers
Post #997 3.81K
​​Стандартные пользовательские литералы. Числовые
#новичкам

Числа подходят для инициализации многих сущностей. Метры, килограммы, градусы и тд. В стандартной библиотеке не так уж и много классов, значения которых можно представить числами. Но тем не менее они есть и литералы становятся довольно полезными при использовании.

Наибольшее распространение числовые пользовательские литералы получили при работе со временем.

Мы все привыкли писать: 5ч или 34мин. И начиная с С++14 мы примерно так и можем оперировать временем. Есть операторы преобразования целых и дробных чисел в годы, дни, часы, минуты, секунды, миллисекунды, микросекунды и наносекунды:

using namespace std::literals;

auto ns = 100ns; // наносекунды
auto us = 100us; // микросекунды
auto ms = 100ms; // миллисекунды
auto s = 100s; // секунды
auto min = 100min; // минуты
auto h = 24h; // часы

auto d = 42d; // дни
auto y = 12y; // года


Вы также можете верхнюю шестерку операторов использовать совместно в операциях:

auto time = 1h + 30min + 90s;


Они совместимы и в результате получается объект общего типа(какой конкретно зависит от реализации, но скорее всего std::chrono::seconds в данном случае)

В крутящемся на проде коде нечасто можно увидеть использование какого-то захардкоженного промежутка времени. Обычно такие штуки уносят в конфигурацию, чтобы иметь возможность подкрутить эти параметры без изменения кода.

Однако литералы времени отлично можно применить в тестах. Например, хотите вы протестировать свой многопоточный шедулер. В качестве простого теста можно запихать в него лямбду, в которой установить значение промиса. А снаружи явно ждать установки значения:

std::promise<void> promise;
auto future = promise.get_future();

dispatcher_->schedule([&] { promise.set_value(); });

EXPECT_EQ(future.wait_for(100ms), std::future_status::ready);


если по истечению 100ms у фьючи не будет статуса "готово", то тест падает.

Интересный факт: оператор суффикс s конфликтует своим именем с оператором преобразования к строке. Но проблема решается автоматически разным типом аргументов. Никаких реальных конфликтов, обычная перегрузка:

std::string_literals::operator"" s(const char*, size_t)
std::chrono_literals::operator"" s(unsigned long long)


Ну и еще есть литералы для комплексных чисел:

using namespace std::literals;

auto c1 = 1.0 + 2.0i; // std::complex<double>(1.0, 2.0)
auto c2 = 3.0i; // std::complex<double>(0.0, 3.0)
auto c3 = 4.0if; // std::complex<float>(0.0f, 4.0f)
auto c4 = 5.0il; // std::complex<long double>(0.0L, 5.0L)


Работает там примерно так же, как в математике.

Не уверен, что кто-то этим пользуется. Но если пользуетесь, расскажите над каким проектом работаете, интересно же.

Be useful. Stay cool.

#cpp14
  • ❤ 29
  • 😁 18
  • 🔥 12
  • 👍 3
  • ⚡ 1
  • 🤯 1
More from @grokaemcpp
  1. Oct 12, 2026​​WAT #новичкам Как вы думаете, результат выражения: bool math = -1 < 1U; будет правдой ил…
  2. Oct 8, 2026​​Strict weak ordering #опытным На первый взгляд, всё выглядит рабочим: мы создаём 40 зака…
  3. Oct 7, 2026​​Где-то баг... #опытным Вот вам код: struct Order { int price; int id; }; int main() { st…
  4. Oct 5, 2026Откуда spurious wakeup на кондваре? #опытным У кондваров есть метод std::condition_variabl…
  5. Oct 1, 2026​​Stacktrace. Tips #опытным Чтобы полноценно работать со стандартными трейсами, нужно знат…
  6. Sep 28, 2026​​Stacktrace #опытным Одна из проблема исключений - непонятно, откуда оно прилетело. Ну да…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →