Funciones Constexpr (C++11)

Una función no de constructor que se declara con un especificador constexpr es una función constexpr . Una función constexpr es una función que se puede invocar dentro de una expresión constante.

Una función constexpr debe cumplir las condiciones siguientes:
  • No es virtual.
  • Su tipo de retorno es un tipo literal.
  • Cada uno de sus parámetros debe ser de tipo literal.
  • Al inicializar el valor de retorno, cada llamada de constructor y conversión implícita es válida en una expresión constante.
  • Su cuerpo de función es = delete o = default; de lo contrario, su cuerpo de función sólo debe contener las siguientes sentencias:
    • null Sentencias
    • static_assert declaraciones
    • Declaraciones typedef que no definen clases ni enumeraciones
    • Directivas using
    • using declaraciones
    • Una sentencia return

Cuando una función de miembro no estático que no es un constructor se declara con el especificador constexpr , dicha función de miembro es constante y el especificador constexpr no tiene ningún otro efecto en el tipo de función. La clase de la que es miembro esa función debe ser un tipo literal.

Los ejemplos siguientes muestran el uso de las funciones de constexpr :
const int array_size1 (int x) {
  return x+1;
}
// Error, constant expression required in array declaration
int array[array_size1(10)];    

constexpr int array_size2 (int x) { 
  return x+1; 
} 
// OK, constexpr functions can be evaluated at compile time
// and used in contexts that require constant expressions. 
int array[array_size2(10)];     

struct S {
  S() { }
  constexpr S(int) { }
  constexpr virtual int f() {  // Error, f must not be virtual.
    return 55;
  }       
};

struct NL {
  ~NL() { }  // The user-provided destructor (even if it is trivial) 
             // makes the type a non-literal type.
};

constexpr NL f1() {  // Error, return type of f1 must be a literal type.
  return NL();
}       

constexpr int f2(NL) {  // Error, the parameter type NL is not a literal type.
  return 55; 
}                 

constexpr S f3() {
  return S();
}

enum { val = f3() };  // Error, initialization of the return value in f3()
                      // uses a non-constexpr constructor.

constexpr void f4(int x) {  // Error, return type should not be void.
  return;
}

constexpr int f5(int x) { // Error, function body contains more than
  if (x<0)                // return statement.
    x = -x;
  return x;
}
Cuando una plantilla de función se declara como una función constexpr , si la instanciación da como resultado una función que no satisface los requisitos de una función constexpr , el especificador constexpr se ignora. Por ejemplo:
template <class C> constexpr NL f6(C c) {  // OK, the constexpr specifier ignored
  return NL();
}
void g() {
  f6(55);  // OK, not used in a constant expression
}

Una llamada a una función constexpr produce el mismo resultado que una llamada a una función equivalente noconstexpr en todos los aspectos, excepto que una llamada a una función constexpr puede aparecer en una expresión constante.

Una función constexpr está implícitamente en línea.

La función main no se puede declarar con el especificador constexpr .