C++11 constexpr function

The C++11 constexpr function is defined like any other function, however, it must meet certain criteria for the function to be valid or to call it as constexpr function.They are:

i)It must return constexpr or literals type.

ii)It cannot be virtual function.

iii)The constexpr function must not contain a compound statement such as:
  a)goto statement
  b)It must not contain a static variable.
  c)It must not contain any uninitialized variable.
  d)It must not contain label statement
  e)It must not contain asm-definition.


Link :C++11 constexpr

Let us now try to define some functions keeping in mind the above criteria.

constexpr int constexprFunc( ) { return 9; } //ok

constexpr int constexprFunc2( ) //work fine
{
if( i==true ) //generate run-time activity
{
… // your code
}

return i;
}

//valid constexpr function
constexpr int constexprFunc3( )
{
typedef int I ;

return 1 ;
}

constexpr int f1( ) //error! contain static varaible
{ static int i; }

constexpr int f2() //Error! uninitialized variable
{ int r; return r; } 

Passing argument to constexpr function

constexpr function doesn’t necessarily only have to return a value, it can also accept arguments. The argument of course cannot be constexpr type but it can be either a const or non-const type. Depending on whether the argument passed is const or non-const the returned value is treated as constexpr value or not.

i)If the argument passed is const or literal or constexpr then the returned value is also constexpr type. This permit the returned value to be treated as valid initializer for the constexpr variable.

constexpr int ret_constexpr( int arg )
{
 return arg*arg ;
}

int main( )
{
int i=90 ;
const int ci=89 , ci1=i ;
constexpr int ce=56 ;

constexpr int value=ret_constexpr( ci ) , //work fine

value1=ret_constexpr(ci1) , //error!

value2=ret_constexpr(ce) , //ok

value2=ret_constexpr(67) ; //ok

return 0 ;
}

The call value1=ret_constexpr(ci1) is an error.



ii)If you pass a non-const value the returned value type is treated as a non-constant type so you cannot assign such value to constexpr variable. But you can assign it to non-constant variable.

constexpr int ret_constexpr( int arg )
{
return arg*arg ;
}

int main( )
{
int i=9 ;
constexpr int ce=89 ;

int val=ret_constexpr(i) , //ok
  val1=ret_constexpr(ce) ; //ok

return 0 ;
}

For the second call constexpr type is passed as the argument and so the return type is also constexpr type but the value can still be assigned to val1. Assigning constexpr to a non-constant variable is allowed because a non-constant type is not specific about its initializer type, it can be const or non-const.


constexpr function as template function

constexpr function can be a template function. The normal template rules apply to constexpr template function and also of course the rule of the constexpr function still applies.

template<class T*>constexpr int templ_func(T t)
{ return t*t; }

int main( )
{
constexpr double f=templ_func(56.67) ;

constexpr int ce=89 ;
constexpr int f=templ_func(ce) ;

return 0 ;
}