C++ constexpr

C++ 11 добавил много всего интересного, но сегодня речь пойдет о constexpr. Концептуально constexpr указывает значение, которое не просто является константой, но и известно во время компиляции. Поэтому если требуется, чтобы переменная была известна на этапе компиляции, то смело помечаем ее constexpr, потому что простой const таких гарантий не дает.

Теперь поговорим про функции. Данное ключевое слово можно применять к функциям, например:

C++ constexpr C++, Constexpr, Факториал, Длиннопост

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

C++ constexpr C++, Constexpr, Факториал, Длиннопост

По-моему круто! Тем самым можно посчитать что-то на этапе компиляции, например, факториал. Да - да, изъезженный пример, но что поделаешь - это классика. Вот как их можно реализовать:

C++ constexpr C++, Constexpr, Факториал, Длиннопост

Почему две разные реализации? Потому что в constexpr в C++11 имеет больше ограничений по сравнению с C++14. Подробнее уже можно почитать на cppreference.com, не буду делать copy-paste.

Ну и напоследок. Нам заполнить массив некоторыми значениями на этапе компиляции. Как будем это делать? Для наглядности возьму тот же факториал.

C++ constexpr C++, Constexpr, Факториал, Длиннопост

Темная уличная шаблонная магия). На самом деле ничего сложного здесь нет, разве что variadic templates, но они хорошо описаны у С. Прата. Проверить работу кода можно здесь: http://rextester.com/KGUP58147.


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

решать использовать такие возможности языка или нет. Я лишь рассказал о такой штуке - переносе части вычислений из run-time в compile-time.


Для подготовки текста использовались материалы из книги замечательного автора S. Meyers "Effective Modern C++".

Лига программистов C/C++

60 постов4.8K подписчиков

Добавить пост

Правила сообщества

Соблюдайте правила Pikabu:

https://pikabu.ru/html.php?id=wtf


Помимо этого ЗАПРЕЩЕНО:

- Размещать в сообществе посты стиля "Подскажите как удалить вирус", "Подскажите как установить программу", "Подскажите как починить монитор/телевизор/мышь/тостер/стиральную машину" или "Напишите за меня лабу в универ". Пожалуйста размещайте такие посты вне этого сообщества или в соответствующих для этого сообществах.

10
Автор поста оценил этот комментарий

Прекрасный пример плохой статьи по программированию.

1) куча воды.

2) куча преимуществ без доводов.

3) дублирование кода... Оо

4) код в картинках... facepalm... Вы б ещё его векторным изображением вставили :D

5) т.е. достаточно одного вызова не захардкоренного значения и всё будет пересчитываться не при компиляции, а в рантайме? тема не раскрыта.


6) Шаблоны для заполнения массива в статье для широкой публики... Вы реально головой не думаете? :D Пример должен быть понятен даже замшелым старичкам, а не заставлять народ ставить вам минус и говорить - во чудак.

раскрыть ветку
4
Автор поста оценил этот комментарий
можно ли более живой пример когда использование consexpr обоснованно?
раскрыть ветку
3
Автор поста оценил этот комментарий
"заполнить массив некоторыми значениями на этапе компиляции. Как будем это делать?" - захардкодить как есть, а если массив совсем большой - загрузим из файла.
раскрыть ветку
Автор поста оценил этот комментарий

Отлично! Запили пост про эти непонятные ... в шаблонах

раскрыть ветку
Автор поста оценил этот комментарий

От себя хотел бы добавить, что в constexpr функциях можно реализовать ветвление через тернарный оператор или constexpr if, но с С++ 17