Я смотрю на новую constexpr
функцию C ++ и не до конца понимаю необходимость в ней.
Например, следующий код:
constexpr int MaxSize()
{
...
return ...;
}
void foo()
{
int vec[MaxSize()];
}
можно заменить на:
int MaxSize()
{
...
return ...;
}
static const int s_maxSize = MaxSize();
foo()
{
int vec[s_maxSize];
}
Обновление
Второй пример на самом деле не стандарт ISO C ++ (спасибо нескольким пользователям за указание на это), но некоторые компиляторы (например, 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
в своем определении. Однако я не могу представить себе никакого практического применения, в котором я когда-либо хотел использовать такие сложные вычисления для определения постоянной времени компиляции.
Итак, даже если это может быть интересной функцией, я все еще задаюсь вопросом, нужна ли она (то есть как часто она может разрешать ситуации, когда макросов недостаточно). Возможно, просмотр нескольких реальных примеров, которые невозможно решить с помощью макросов, поможет мне изменить это мнение.