Рубрики

Понимание спецификатора constexpr в C ++

constexpr — это функция, добавленная в C ++ 11. Основная идея — повышение производительности программ за счет выполнения вычислений во время компиляции, а не во время выполнения. Обратите внимание, что как только программа скомпилирована и завершена для разработчика, она запускается пользователями несколько раз. Идея состоит в том, чтобы тратить время на компиляцию и экономить время во время выполнения (аналогично метапрограммированию шаблонов )

constexpr указывает, что значение объекта или функции может быть оценено во время компиляции, а выражение может быть использовано в других константных выражениях. Например, в приведенном ниже коде product () оценивается во время компиляции.

// функция constexpr для произведения двух чисел.
// Указывая constexpr, мы предлагаем компилятор
// оценить значение во время компиляции

constexpr int product(int x, int y)

{

    return (x * y);

}

  

int main()

{

    const int x = product(10, 20);

    cout << x;

    return 0;

}

Выход :

200

Функция должна быть объявлена как constexpr

  1. В C ++ 11 функция constexpr должна содержать только один оператор return. C ++ 14 допускает более одного утверждения.
  2. Функция constexpr должна ссылаться только на постоянные глобальные переменные.
  3. Функция constexpr может вызывать только другую функцию constexpr, а не простую функцию.
  4. Функция не должна иметь тип void, и некоторые операторы, такие как приращение префикса (++ v), не разрешены в функции constexpr.

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

Пример улучшения производительности от constexpr:
Рассмотрим следующую программу на C ++

// Программа на C ++ для демонстрации использования constexpr
#include<iostream>

using namespace std;

  

constexpr long int fib(int n)

{

    return (n <= 1)? n : fib(n-1) + fib(n-2);

}

  

int main ()

{

    // значение res вычисляется во время компиляции.

    const long int res = fib(30);

    cout << res;

    return 0;

}

Когда вышеуказанная программа запускается в GCC, она занимает 0,003 секунды (мы можем измерить время с помощью команды времени )

Если мы удалим const из строки ниже, то значение fib (5) не будет вычислено во время компиляции, потому что результат constexpr не используется в выражении const.

Change,
  const long int res = fib(30);  
To,
  long int res = fib(30);

После внесения вышеуказанных изменений время, затраченное программой, увеличивается на 0,017 секунды .

constexpr с конструкторами:
constexpr также может быть использован в конструкторах и объектах. Смотрите это для всех ограничений на конструкторы, которые могут использовать constexpr.

// C ++ программа для демонстрации использования constexpr в конструкторе
#include <bits/stdc++.h>

using namespace std;

  
// Класс с конструктором и функцией constexpr

class Rectangle

{

    int _h, _w;

public:

    // конструктор constexpr

    constexpr Rectangle (int h, int w) : _h(h), _w(w) {}

      

    constexpr int getArea ()  {   return _h * _w; }

};

  
// программа драйвера для тестирования функции

int main()

{

    // Ниже объект инициализируется во время компиляции

    constexpr Rectangle obj(10, 20);

    cout << obj.getArea();

    return 0;

}

Выход :

200

constexpr против const
Они служат разным целям. constexpr в основном для оптимизации, а const для практически постоянных объектов, таких как значение Pi.
Оба они могут быть применены к методам членов. Методы-члены сделаны const, чтобы убедиться, что нет случайных изменений метода. С другой стороны, идея использования constexpr состоит в том, чтобы вычислять выражения во время компиляции, чтобы сэкономить время при запуске кода.
const может использоваться только с нестатической функцией-членом, тогда как constexpr может использоваться с функциями-членами и не-членами, даже с конструкторами, но с условием, что аргумент и возвращаемый тип должны быть литеральными типами.

Эта статья предоставлена Уткаршем Триведи. Пожалуйста, напишите комментарии, если вы обнаружите что-то неправильное, или вы хотите поделиться дополнительной информацией по обсуждаемой теме

Рекомендуемые посты:

Понимание спецификатора constexpr в C ++

0.00 (0%) 0 votes