Any type_traits or method could find out the parameters is a constexpr or not?
Example
size_t fibo_runtime(size_t num)
{
//implementation
}
constexpr
I think this may get you what you want
#include <iostream>
template <typename T>
class is_constexpr
{
typedef char true_type ;
struct false_type { true_type _[2] ; } ;
template <typename U>
static true_type has_constexpr( U & ) ;
template <typename U>
static false_type has_constexpr(...) ;
public:
enum { value = ( sizeof(has_constexpr<T>(0)) == sizeof(true_type)) } ;
} ;
int main()
{
constexpr int i = 10 ;
int k = 20 ;
std::cout << is_constexpr<decltype(i)>::value << std::endl ;
std::cout << is_constexpr<decltype(k)>::value << std::endl ;
}
I used Understanding SFINAE as a reference.
Doing some more research I think I the answer to the other part of the question is yes, since it looks a constexpr
function template is not always usable in a constant expression. So this leads to a solution like so, with this somewhat contrived example:
template <typename T>
T f2( T num )
{
return num + 1;
}
template <typename T>
constexpr T f1( T num )
{
return num ;
}
template <typename T>
constexpr T f(T num)
{
return is_constexpr<T>::value ? f1(num) : f2(num) ;
}
Within the function, it isn't possible to check the parameters to see if the complete calling expression is a constant expression. But you can implement a macro at the call site to test the same thing, evaluating to true_type
or false_type
at compile time depending on whether the expression is a constant expression
IS_A_CONSTANT_EXPRESSION( fibo(5) ) // is constant
IS_A_CONSTANT_EXPRESSION( fibo(time(NULL) ) // is not constant
The details are in this answer to another question. (My own answer, apologies for cross posting!)
You could then implement another macro, FIBO( expr )
to wrap this up nicely and call the correct version as appropriate.
The very nature of constant expression (constexpr
) is to be constant. So runtime evaluation or not, they will not change any of their behavior and the evaluation will never be done at runtime.
If you use a constexpr
function at runtime (which is not simply by calling it straightforwardly), then it will be called as a normal function, as the expression cannot be resolved by nature as constant during runtime.
If you want to achieve some different implementation depending on compile-time or runtime it will (if you achieve it) be really disturbing for the developer as the function would not have the same behavior depending on how you call it ! Thus it becomes clear that such behavior could not / will not / should not be implemented.
If you want to specialize a function for compile-time computation, use a different function to clearly state your intentions.