Я смотрел новую функцию constexpr
на С++, и я не совсем понимаю ее необходимость.
Например, следующий код:
constexpr int MaxSize()
{
...
return ...;
}
void foo()
{
int vec[MaxSize()];
}
можно заменить на:
int MaxSize()
{
...
return ...;
}
static const int s_maxSize = MaxSize();
foo()
{
int vec[s_maxSize];
}
Обновление
Второй пример на самом деле не стандартный ISO С++ (благодаря нескольким пользователям для указания этого), но некоторые компиляторы (например, gcc) поддерживают его. Таким образом, это не const
, что делает программу действительной, но тот факт, что gcc поддерживает эту нестандартную функцию. (Насколько мне известно, это возможно только тогда, когда массив определяется как локальный для функции или метода, поскольку размер глобального массива должен быть известен во время компиляции.) Если я скомпилирую без параметров -std=c++98 -pedantic-errors
, даже код
int MaxSize()
{
return 10;
}
void foo()
{
int vec[MaxSize()];
}
будет компилироваться с помощью gcc.
Итак, я постараюсь перефразировать мой вопрос, принимая во внимание отзывы, которые пришли до сих пор (а также некоторое дополнительное чтение, которое я сделал за это время).
Я использую ключевое слово const
. С помощью const
я могу определить константу, которая имеет определенное значение за все время жизни. Константу можно инициализировать любым выражением, которое оценивается один раз, а именно при создании константы. Для этих случаев я считаю, что constexpr
довольно бесполезен: он вводит очень небольшую оптимизацию в том, что выражение, определяющее значение константы, будет вычисляться во время компиляции вместо времени выполнения. Каждый раз, когда мне нужна постоянная времени выполнения со сложной инициализацией, я использую ключевое слово const
.
Так что constexpr
может пригодиться в ситуациях, когда нам нужно инициализировать константу во время компиляции. Одним из примеров является векторное определение: стандарт не поддерживает определение размера во время выполнения. Другим примером является шаблон с одним или несколькими непиковыми параметрами.
В таких случаях я обычно использую макросы:
#define MAX_SIZE (10)
void foo()
{
int vec[MAX_SIZE];
}
но, если я правильно понимаю, функции constexpr
более мощные, чем макросы, поскольку они позволяют рекурсивные вызовы функций constexpr
в их определении. Однако я не могу придумать никакого практического приложения, в котором я когда-либо хотел использовать такое сложное вычисление для определения константы времени компиляции.
Итак, даже если это может быть интересной особенностью, я все же задаюсь вопросом, нужно ли это (то есть, как часто он может решать ситуации, когда макросов недостаточно). Возможно, посмотрите на несколько реальных примеров, которые не могут быть решены с помощью макросов, поможет мне изменить это мнение.