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.