Entendiendo el especificador constexpr en C++

constexpr es una función agregada en C++ 11. La idea principal es una mejora del rendimiento de los programas al realizar cálculos en tiempo de compilación en lugar de tiempo de ejecución. Tenga en cuenta que una vez que el desarrollador compila y finaliza un programa, los usuarios lo ejecutan varias veces. La idea es dedicar tiempo a la compilación y ahorrar tiempo en tiempo de ejecución (similar a la metaprogramación de plantillas ). constexpr especifica que el valor de un objeto o una función se puede evaluar en tiempo de compilación y la expresión se puede usar en otras expresiones constantes. 

Ejemplo:

CPP

// C++ program to demonstrate constexpr function for product
// of two numbers. By specifying constexpr, we suggest
// compiler to to evaluate value at compile time
#include <iostream>
  
constexpr int product(int x, int y) { return (x * y); }
  
int main()
{
    constexpr int x = product(10, 20);
    std::cout << x;
    return 0;
}

Producción :

200

Una función se declara como constexpr

  1. En C++ 11, una función constexpr debe contener solo una declaración de retorno. C++ 14 permite más de una instrucción.
  2. La función constexpr debe referirse solo a variables globales constantes.
  3. La función constexpr solo puede llamar a otra función constexpr, no a una función simple.
  4. La función no debe ser de tipo nulo y algunos operadores como el incremento de prefijo (++v) no están permitidos en la función constexpr.

 constexpr vs funciones en línea

Constexpr

Funciones en línea

Elimina las llamadas a funciones a medida que evalúa el código/expresiones en tiempo de compilación. Apenas elimina ninguna llamada de función, ya que realiza una acción en la expresión en el tiempo de ejecución.
Es posible evaluar el valor de la variable o función en tiempo de compilación. No es posible evaluar el valor de la función o variable en tiempo de compilación.
No implica vinculación externa. Implica vinculación externa.

Ejemplo de mejora del rendimiento por constexpr: 

CPP

// A C++ program to demonstrate the use of constexpr 
#include<iostream> 
using namespace std; 
  
constexpr long int fib(int n) 
{ 
    return (n <= 1)? n : fib(n-1) + fib(n-2); 
} 
  
int main () 
{ 
    // value of res is computed at compile time. 
    constexpr long int res = fib(30); 
    cout << res; 
    return 0; 
} 

Producción:

832040

Cuando el programa anterior se ejecuta en GCC, toma 0.003 segundos (Podemos medir el tiempo usando el comando time ) Si eliminamos const de la línea a continuación, entonces el valor de fib(5) no se evalúa en tiempo de compilación, porque el El resultado de constexpr no se usa en una expresión const.

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

Después de realizar el cambio anterior, el tiempo que tarda el programa aumenta en 0,017 segundos .

constexpr con constructores: un constructor que se declara con un especificador constexpr es un constructor constexpr y también se puede usar constexpr para crear constructores y objetos. Un constructor constexpr está implícitamente en línea.

Restricciones sobre los constructores que pueden usar constexpr:

  • Sin clase base virtual
  • Cada parámetro debe ser literal .
  • No es una función de bloque de prueba.

Ejemplo:

CPP

// C++ program to demonstrate uses 
// of constexpr in constructor 
#include <bits/stdc++.h> 
using namespace std; 
  
// A class with constexpr 
// constructor and function 
class Rectangle 
{ 
    int _h, _w; 
public: 
    // A constexpr constructor 
    constexpr Rectangle (int h, int w) : _h(h), _w(w) {} 
      
    constexpr int getArea () { return _h * _w; } 
}; 
  
// driver program to test function 
int main() 
{ 
    // Below object is initialized at compile time 
    constexpr Rectangle obj(10, 20); 
    cout << obj.getArea(); 
    return 0; 
} 

Producción :

200

 constexpr vs const 

Sirven para diferentes propósitos. constexpr es principalmente para optimización mientras que const es para objetos prácticamente constantes como el valor de Pi. Ambos se pueden aplicar a métodos de miembros. Los métodos de miembro se hacen constantes para asegurarse de que no haya cambios accidentales en el método. Por otro lado, la idea de usar constexpr es calcular expresiones en tiempo de compilación para que se pueda ahorrar tiempo cuando se ejecuta el código. const solo se puede usar con funciones miembro no estáticas, mientras que constexpr se puede usar con funciones miembro y no miembro, incluso con constructores, pero con la condición de que el argumento y el tipo de retorno sean de tipo literal. 

Este artículo es una contribución de Utkarsh Trivedi . Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *