Пользовательские литералы в C++11
Более полугода прошло с момента принятия стандарта C++11. В сети можно найти много материалов посвященных новому стандарту, однако большинство из них касаются самых простых возможностей, самых сладких. Я говорю о лямбда-функциях, системе автоматического выведения типов, новых спецификаторах, умных указателях и т.д. Да, это действительно интересные вещи и, можно смело сказать, они одни из самых полезных и часто используемых. Но на них свет клином не сошелся, и новенький C++11 предлагает нам не только их.
Ниже я хочу рассказать о пользовательских литералах — весьма полезном средстве, хоть и не в повседневных целях.
Что такое литерал?
Литерал — это некоторое выражение, создающее объект. Литералы появились не только в C++11, они были и в C++03. Например, есть литералы для создания символа, строки, вещественных чисел, и т.д.
Все это литералы. С понятием литералов, думаю, мы разобрались. Самое время вернуться к C++11.
Пользовательские литералы в C++11
Как уже было отмечено выше, новый стандарт предлагает средства для создания пользовательских литералов. Существует две категории пользовательских литералов: сырые литералы (raw) и литералы для встроенных типов (cooked).
Стоит, однако, заметить, что C++ позволяет создавать только литералы-суфиксы. Иными словами, создать литералы префиксы (как, например, 0x), или префиксо-суфиксные (как «») — не получится.
Литералы для численных типов
Начнем с литералов для встроенных типов. Чтобы создать литерал для численных типов необходимо воспользоваться одной из двух сигнатур:
Использование литерала будет осуществляется следующим образом:
- литерал для целых чисел в качестве аргумента принимает unsigned long long
- литерал для вещественных чисел в качестве аргумента принимает long double
Ниже приведен пример литерала, преобразовывающего минуты в секунды.
Литералы для строковых типов
Для создания литерала этого типа, необходимо воспользоваться одной из следующих сигнатур:
Сигнатура выбирается в зависимости от типа строки:
Пример литерала преобразующего C-style строку в std::string приведен ниже.
Сырые литералы
Ну и наконец настало время сырого литерала. Сигнатура сырого литерала выглядит следующим образом:
Этот тип литералов приходит на помощь тогда, когда входное число надо разобрать посимвольно. Т.e. в этом случае число передается в оператор как строка. Если не совсем понятно, взгляните на приведенный ниже код:
Используя данный тип литералов, можно написать литерал преобразующий двоичное число в десятичное. Например вот так:
Существует еще одна сигнатура для сырых литералов. Основана она на применении Variadic Template:
Преимущества литералов на базе Variadic Template заключается в том, что они могут вычисляться на этапе компиляции. Тот же литерал преобразования двоичного числа в десятичное может быть переписан так:
У внимательно читателя мог возникнуть вопрос: «А что если создать и сырой литерал, и литерал для числа с одним и тем же именем? Какой литерал компилятор применит?». Стандарт по этому поводу дает точный ответ и говорит о попытке компилятора применить литералы в следующем порядке:
- operator «» _x (unsigned long long) или operator «» _x (long double)`
- operator «» _x (const char* raw)
- operator «» _x <‘c1’, ‘c2’, . ‘cn’>
Выводы
Бьёрн Страуструп на конференции Going Native 2012 приводил полезный пример использования литералов. Мне кажется, он наглядно демонстрирует факт повышения читаемости кода, а также снижает вероятность ошибиться.
Механизм пользовательских литералов — это полезный в некоторых случаях инструмент. Использовать его где попало не стоит. Подумайте дважды, прежде чем их использовать, ведь литералы коварны: они могут…
Литерал (информатика)
Литерал (англ. literal — константа) — запись в исходном коде компьютерной программы, представляющая собой фиксированное значение [1] .
Содержание
Описание
Литералы представляют собой константы, непосредственно включаемые в текст программы в отличие от прочих данных — констант и переменных, обращение к которым осуществляется посредством ссылок [1] . Литералы не могут быть изменены в тексте программы.
В следующем примере 1 и Кот это литералы, а a1, c и cat — переменные:
Литерал в языке Python — это выражение, создающее объект.
Типы литералов
Почти все языки программирования допускают использование литералов элементарных типов. Однако, использование различных типов литералов, а также их запись в программах отличается.
Обычно выделяют следующие элементарные типы литералов:
Числовые литералы — литералы, для записи чисел. Иногда, числовые литералы детализируются целые литералы, дробные литералы, с различной точностью представления и записанные в различной системе счисления (например, битовые литералы в PL/I). Обычно, в программах числовые литералы записываются непосредственно числом. В следующем примере 100 и 3.1415 — числовые литералы:
Строковые литералы, обычно, представляют собой строку символов, заключённую в кавычки или скобки. Иногда выделяют, также, символьные литералы, включающие один символ. В разных языках программирования допускаются различные типы кавычек. Например, в следующем примере на языке JavaScript один и два — строковые литералы записанные с использованием различных допустимых типов кавычек:
Логические литералы, Логические значения — два литерала: true и false или их аналоги — T, t, Y, y, F, f, N, n, NIL и т. п.. Например:
Литерал ссылочного типа, адрес в памяти — обычно, числовые литералы, указывающие на ячейку в памяти.
Null-литерал, Пустое значение — особый тип литерала, в зависимости от языка программирования, относящийся к ссылочному либо объектному типу. Единственное допустимое значение этого типа литералов null, или аналог, например NIL, None, Nothing — ссылка никуда не ведёт либо объект отсутствует.
Регулярные выражения. В некоторых языках программирования регулярные выражения представляют собой литерал особого типа для поиска по шаблону [2] . Например:
В некоторых объектно ориентированных языках программирования (например, ECMAScript v3) допускается использовать выражения, которые служат массивами-литералами и объектами-литералами [2] . Например:
Иногда анонимные функции относят к литералам-функциям, а анонимные объекты к литералам-объектам.
Что такое литералы? [дубликат]
В следующем примере 1 и Кот это литералы, а a1 , c и cat — переменные:
Если "Литерал" это фиксированное значение, то зачем это терминология когда есть термин "константа" ?
![]()
Потому что в программировании константа — это переменная с фиксированнным значением.
В то же время и само значение такой переменной — это в общем-то тоже константа .
Видимо, поэтому, чтобы избежать неоднозначности толкования — о чём же мы всё-таки говорим, когда в программировании произносим термин константа — ввели термин литерал .
Поэтому в программировании обычно понимают так:
- константа — это переменная, содержащая фиксированное значение (нонсенс, если подумать — "переменная" и в то же время "фиксированная", но так сложилось)
- литерал — это само фиксированное значение, которое присваивается переменной-константе или ещё каким-то образом используется в программе (в общем-то не обязательно его куда-то присваивать)
константа и литерал — это разные сущности
константа — это данные, которые нельзя изменять
а литералы — это некоторые числовые или цифровые префиксы и суффиксы, которые описывают данные, хранящиеся в переменных и константах
или например в C++11 появились литералы для времени —
ms — это литерал
т.е. когда вы используете const — вы говорите компилятору, что значение данной переменной не может быть изменено напрямую (обходы есть, но сейчас не об этом)
а когда вы используете литералы, то вы говорите компилятору как именно интерпретировать данные, которые вы записываете в переменную